From 7a42ffc3827e0909266974acea6d4b243a8f11b7 Mon Sep 17 00:00:00 2001 From: wpaul Date: Sun, 7 Mar 2004 02:49:06 +0000 Subject: Add preliminary support for PCMCIA devices in addition to PCI/cardbus. if_ndis.c has been split into if_ndis_pci.c and if_ndis_pccard.c. The ndiscvt(8) utility should be able to parse device info for PCMCIA devices now. The ndis_alloc_amem() has moved from kern_ndis.c to if_ndis_pccard.c so that kern_ndis.c no longer depends on pccard. NOTE: this stuff is not guaranteed to work 100% correctly yet. So far I have been able to load/init my PCMCIA Cisco Aironet 340 card, but it crashes in the interrupt handler. The existing support for PCI/cardbus devices should still work as before. --- usr.sbin/ndiscvt/inf.c | 162 ++++++++++++++++++++++++++++++++++++++++++--- usr.sbin/ndiscvt/ndiscvt.c | 6 +- 2 files changed, 159 insertions(+), 9 deletions(-) (limited to 'usr.sbin') diff --git a/usr.sbin/ndiscvt/inf.c b/usr.sbin/ndiscvt/inf.c index 100fd90..de6c342 100644 --- a/usr.sbin/ndiscvt/inf.c +++ b/usr.sbin/ndiscvt/inf.c @@ -57,8 +57,10 @@ static struct assign *find_assign (const char *, const char *); static struct section *find_section (const char *); -static void dump_deviceids (void); +static void dump_deviceids_pci (void); +static void dump_deviceids_pcmcia (void); static void dump_pci_id (const char *); +static void dump_pcmcia_id (const char *); static void dump_regvals (void); static void dump_paramreg (const struct section *, const struct reg *, int); @@ -76,8 +78,11 @@ inf_parse (FILE *fp, FILE *outfp) yyin = fp; yyparse(); - dump_deviceids(); + dump_deviceids_pci(); + dump_deviceids_pcmcia(); + fprintf(outfp, "#ifdef NDIS_REGVALS\n"); dump_regvals(); + fprintf(outfp, "#endif /* NDIS_REGVALS */\n"); return (0); } @@ -145,6 +150,54 @@ find_section (const char *s) } static void +dump_pcmcia_id(const char *s) +{ + char *manstr, *devstr; + char *p0, *p; + + p0 = __DECONST(char *, s); + + p = strchr(p0, '\\'); + if (p == NULL) + return; + p0 = p + 1; + + p = strchr(p0, '-'); + if (p == NULL) + return; + *p = '\0'; + + manstr = p0; + + /* Convert any underscores to spaces. */ + + while (*p0 != '\0') { + if (*p0 == '_') + *p0 = ' '; + p0++; + } + + p0 = p + 1; + p = strchr(p0, '-'); + if (p == NULL) + return; + *p = '\0'; + + devstr = p0; + + /* Convert any underscores to spaces. */ + + while (*p0 != '\0') { + if (*p0 == '_') + *p0 = ' '; + p0++; + } + + fprintf(ofp, "\t\\\n\t{ \"%s\", \"%s\", ", manstr, devstr); + return; +} + +static void dump_pci_id(const char *s) { char *p; @@ -178,7 +231,7 @@ dump_pci_id(const char *s) } static void -dump_deviceids() +dump_deviceids_pci() { struct assign *manf, *dev; struct section *sec; @@ -201,8 +254,25 @@ dump_deviceids() } else sec = find_section(manf->vals[0]); - /* Emit start of device table */ - fprintf (ofp, "#define NDIS_DEV_TABLE"); + /* See if there are any PCI device definitions. */ + + TAILQ_FOREACH(assign, &ah, link) { + if (assign->section == sec) { + dev = find_assign("strings", assign->key); + if (strcasestr(assign->vals[1], "PCI") != NULL) { + found++; + break; + } + } + } + + if (found == 0) + return; + + found = 0; + + /* Emit start of PCI device table */ + fprintf (ofp, "#define NDIS_PCI_DEV_TABLE"); retry: @@ -218,11 +288,87 @@ retry: /* Emit device IDs. */ if (strcasestr(assign->vals[1], "PCI") != NULL) dump_pci_id(assign->vals[1]); - else if (strcasestr(assign->vals[1], "PCMCIA") != NULL) + else continue; -#ifdef notdef + /* Emit device description */ + fprintf (ofp, "\t\\\n\t\"%s\" },", dev->vals[0]); + found++; + } + } + + /* Someone tried to fool us. Shame on them. */ + if (!found) { + found++; + sec = find_section(manf->vals[0]); + goto retry; + } + + /* Emit end of table */ + + fprintf(ofp, "\n\n"); + +} + +static void +dump_deviceids_pcmcia() +{ + struct assign *manf, *dev; + struct section *sec; + struct assign *assign; + char xpsec[256]; + int found = 0; + + /* Find manufacturer name */ + manf = find_assign("Manufacturer", NULL); + + /* Find manufacturer section */ + if (manf->vals[1] != NULL && + (strcasecmp(manf->vals[1], "NT.5.1") == 0 || + strcasecmp(manf->vals[1], "NTx86") == 0 || + strcasecmp(manf->vals[1], "NTx86.5.1") == 0)) { + /* Handle Windows XP INF files. */ + snprintf(xpsec, sizeof(xpsec), "%s.%s", + manf->vals[0], manf->vals[1]); + sec = find_section(xpsec); + } else + sec = find_section(manf->vals[0]); + + /* See if there are any PCMCIA device definitions. */ + + TAILQ_FOREACH(assign, &ah, link) { + if (assign->section == sec) { + dev = find_assign("strings", assign->key); + if (strcasestr(assign->vals[1], "PCMCIA") != NULL) { + found++; + break; + } + } + } + + if (found == 0) + return; + + found = 0; + + /* Emit start of PCMCIA device table */ + fprintf (ofp, "#define NDIS_PCMCIA_DEV_TABLE"); + +retry: + + /* + * Now run through all the device names listed + * in the manufacturer section and dump out the + * device descriptions and vendor/device IDs. + */ + + TAILQ_FOREACH(assign, &ah, link) { + if (assign->section == sec) { + dev = find_assign("strings", assign->key); + /* Emit device IDs. */ + if (strcasestr(assign->vals[1], "PCMCIA") != NULL) dump_pcmcia_id(assign->vals[1]); -#endif + else + continue; /* Emit device description */ fprintf (ofp, "\t\\\n\t\"%s\" },", dev->vals[0]); found++; diff --git a/usr.sbin/ndiscvt/ndiscvt.c b/usr.sbin/ndiscvt/ndiscvt.c index 58068aa..d1a29b3 100644 --- a/usr.sbin/ndiscvt/ndiscvt.c +++ b/usr.sbin/ndiscvt/ndiscvt.c @@ -236,8 +236,10 @@ main(int argc, char *argv[]) } if (inffile == NULL) { + fprintf (outfp, "#ifdef NDIS_REGVALS\n"); fprintf (outfp, "ndis_cfg ndis_regvals[] = {\n"); fprintf (outfp, "\t{ NULL, NULL, { 0 }, 0 }\n"); + fprintf (outfp, "#endif /* NDIS_REGVALS */\n"); fprintf (outfp, "};\n\n"); } else { @@ -250,7 +252,8 @@ main(int argc, char *argv[]) fclose(fp); } - fprintf(outfp, "\n\nextern unsigned char drv_data[];\n\n"); + fprintf(outfp, "\n#ifdef NDIS_IMAGE\n"); + fprintf(outfp, "\nextern unsigned char drv_data[];\n\n"); fprintf(outfp, "__asm__(\".data\");\n"); fprintf(outfp, "__asm__(\".type drv_data, @object\");\n"); @@ -278,6 +281,7 @@ main(int argc, char *argv[]) done: + fprintf(outfp, "#endif /* NDIS_IMAGE */\n"); if (fp != NULL) fclose(fp); fclose(outfp); -- cgit v1.1