aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/compat/ndis/kern_ndis.c41
-rw-r--r--sys/compat/ndis/subr_ndis.c4
2 files changed, 41 insertions, 4 deletions
diff --git a/sys/compat/ndis/kern_ndis.c b/sys/compat/ndis/kern_ndis.c
index f633a1c895d4..b59ba878e703 100644
--- a/sys/compat/ndis/kern_ndis.c
+++ b/sys/compat/ndis/kern_ndis.c
@@ -771,7 +771,9 @@ ndis_convert_res(arg)
ndis_miniport_block *block;
device_t dev;
struct resource_list *brl;
- struct resource_list_entry *brle;
+ struct resource_list brl_rev;
+ struct resource_list_entry *brle, *n;
+ int error = 0;
sc = arg;
block = &sc->ndis_block;
@@ -791,7 +793,34 @@ ndis_convert_res(arg)
brl = BUS_GET_RESOURCE_LIST(device_get_parent(dev), dev);
if (brl != NULL) {
+
+ /*
+ * We have a small problem. Some PCI devices have
+ * multiple I/O ranges. Windows orders them starting
+ * from lowest numbered BAR to highest. We discover
+ * them in that order too, but insert them into a singly
+ * linked list head first, which means when time comes
+ * to traverse the list, we enumerate them in reverse
+ * order. This screws up some drivers which expect the
+ * BARs to be in ascending order so that they can choose
+ * the "first" one as their register space. Unfortunately,
+ * in order to fix this, we have to create our own
+ * temporary list with the entries in reverse order.
+ */
+ SLIST_INIT(&brl_rev);
SLIST_FOREACH(brle, brl, link) {
+ n = malloc(sizeof(struct resource_list_entry),
+ M_TEMP, M_NOWAIT);
+ if (n == NULL) {
+ error = ENOMEM;
+ goto bad;
+ }
+ bcopy((char *)brle, (char *)n,
+ sizeof(struct resource_list_entry));
+ SLIST_INSERT_HEAD(&brl_rev, n, link);
+ }
+
+ SLIST_FOREACH(brle, &brl_rev, link) {
switch (brle->type) {
case SYS_RES_IOPORT:
prd->cprd_type = CmResourceTypePort;
@@ -820,7 +849,15 @@ ndis_convert_res(arg)
block->nmb_rlist = rl;
- return(0);
+bad:
+
+ while (!SLIST_EMPTY(&brl_rev)) {
+ n = SLIST_FIRST(&brl_rev);
+ SLIST_REMOVE_HEAD(&brl_rev, link);
+ free (n, M_TEMP);
+ }
+
+ return(error);
}
/*
diff --git a/sys/compat/ndis/subr_ndis.c b/sys/compat/ndis/subr_ndis.c
index 9fa87e9030b3..ba6f285b267c 100644
--- a/sys/compat/ndis/subr_ndis.c
+++ b/sys/compat/ndis/subr_ndis.c
@@ -1906,12 +1906,12 @@ ndis_init_event(event)
ndis_event *event;
{
/*
- * NDIS events are always synchronization
+ * NDIS events are always notification
* events, and should be initialized to the
* not signaled state.
*/
- ntoskrnl_init_event(&event->ne_event, EVENT_TYPE_SYNC, FALSE);
+ ntoskrnl_init_event(&event->ne_event, EVENT_TYPE_NOTIFY, FALSE);
return;
}