summaryrefslogtreecommitdiffstats
path: root/sys/dev/if_ndis/if_ndis.c
diff options
context:
space:
mode:
authorwpaul <wpaul@FreeBSD.org>2003-12-18 03:51:21 +0000
committerwpaul <wpaul@FreeBSD.org>2003-12-18 03:51:21 +0000
commit74b1363ea90e609ecd017b43c841fa54f54127ff (patch)
tree5ee952471a833e8a8748d227d48d1f385c5adb16 /sys/dev/if_ndis/if_ndis.c
parent3242fb60cccb7ee9ecca553025efbe11e7ae4cbe (diff)
downloadFreeBSD-src-74b1363ea90e609ecd017b43c841fa54f54127ff.zip
FreeBSD-src-74b1363ea90e609ecd017b43c841fa54f54127ff.tar.gz
Deal with the duplicate sysctl leaf problem. A .inf file may contain
definitions for more than one device (usually differentiated by the PCI subvendor/subdevice ID). Each device also has its own tree of registry keys. In some cases, each device has the same keys, but sometimes each device has a unique tree but with overlap. Originally, I just had ndiscvt(8) dump out all the keys it could find, and we would try to apply them to every device we could find. Now, each key has an index number that matches it to a device in the device ID list. This lets us create just the keys that apply to a particular device. I also added an extra field to the device list to hold the subvendor and subdevice ID. Some devices are generic, i.e. there is no subsystem definition. If we have a device that doesn't match a specific subsystem value and we have a generic entry, we use the generic entry.
Diffstat (limited to 'sys/dev/if_ndis/if_ndis.c')
-rw-r--r--sys/dev/if_ndis/if_ndis.c33
1 files changed, 31 insertions, 2 deletions
diff --git a/sys/dev/if_ndis/if_ndis.c b/sys/dev/if_ndis/if_ndis.c
index b6beb3d..5e1f9b9 100644
--- a/sys/dev/if_ndis/if_ndis.c
+++ b/sys/dev/if_ndis/if_ndis.c
@@ -85,7 +85,7 @@ static struct ndis_type ndis_devs[] = {
#ifdef NDIS_DEV_TABLE
NDIS_DEV_TABLE
#endif
- { 0, 0, NULL }
+ { 0, 0, 0, NULL }
};
#define __stdcall __attribute__((__stdcall__))
@@ -178,7 +178,9 @@ ndis_probe(dev)
while(t->ndis_name != NULL) {
if ((pci_get_vendor(dev) == t->ndis_vid) &&
- (pci_get_device(dev) == t->ndis_did)) {
+ (pci_get_device(dev) == t->ndis_did) &&
+ (pci_read_config(dev, PCIR_SUBVEND_0, 4) ==
+ t->ndis_subsys)) {
device_set_desc(dev, t->ndis_name);
return(0);
}
@@ -201,6 +203,9 @@ ndis_attach(dev)
struct ifnet *ifp;
int unit, error = 0, rid, len;
void *img;
+ struct ndis_type *t;
+ int devidx = 0, defidx = 0;
+
sc = device_get_softc(dev);
unit = device_get_unit(dev);
@@ -297,6 +302,30 @@ ndis_attach(dev)
sc->ndis_regvals = ndis_regvals;
sc->ndis_iftype = PCIBus;
+ /* Figure out exactly which device we matched. */
+
+ t = ndis_devs;
+
+ while(t->ndis_name != NULL) {
+ if ((pci_get_vendor(dev) == t->ndis_vid) &&
+ (pci_get_device(dev) == t->ndis_did)) {
+ if (t->ndis_subsys == 0)
+ defidx = devidx;
+ else {
+ if (t->ndis_subsys ==
+ pci_read_config(dev, PCIR_SUBVEND_0, 4))
+ break;
+ }
+ }
+ t++;
+ devidx++;
+ }
+
+ if (ndis_devs[devidx].ndis_name == NULL)
+ sc->ndis_devidx = defidx;
+ else
+ sc->ndis_devidx = devidx;
+
sysctl_ctx_init(&sc->ndis_ctx);
/* Create sysctl registry nodes */
OpenPOWER on IntegriCloud