static int fe_pccard_attach(device_t dev) { struct fe_softc *sc; const struct fe_pccard_product *pp; int error; /* Prepare for the device probe process. */ sc = device_get_softc(dev); sc->sc_unit = device_get_unit(dev); pp = (const struct fe_pccard_product *) pccard_product_lookup(dev, (const struct pccard_product *)fe_pccard_products, sizeof(fe_pccard_products[0]), NULL); if (pp == NULL) return (ENXIO); if (pp->mpp_flags & MPP_MBH10302) error = fe_probe_mbh(dev, pp); else error = fe_probe_tdk(dev, pp); if (error != 0) { fe_release_resource(dev); return (error); } error = fe_alloc_irq(dev, 0); if (error != 0) { fe_release_resource(dev); return (error); } return (fe_attach(dev)); }
static int ncv_pccard_probe(device_t dev) { const struct ncv_product *pp; const char *vendorstr; const char *prodstr; if ((pp = (const struct ncv_product *) pccard_product_lookup(dev, (const struct pccard_product *) ncv_products, sizeof(ncv_products[0]), NULL)) != NULL) { if (pp->prod.pp_name != NULL) device_set_desc(dev, pp->prod.pp_name); device_set_flags(dev, pp->flags); return(0); } if (pccard_get_vendor_str(dev, &vendorstr)) return(EIO); if (pccard_get_product_str(dev, &prodstr)) return(EIO); if (strcmp(vendorstr, "RATOC System Inc.") == 0 && strncmp(prodstr, "SOUND/SCSI2 CARD", 16) == 0) { device_set_desc(dev, "RATOC REX-5572"); device_set_flags(dev, FLAGS_REX5572); return (BUS_PROBE_DEFAULT); } return(EIO); }
static const struct ep_pccard_product * ep_pccard_lookup(device_t dev) { return ((const struct ep_pccard_product *)pccard_product_lookup(dev, (const struct pccard_product *)ep_pccard_products, sizeof(ep_pccard_products[0]), NULL)); }
static int wi_pccard_probe(device_t dev) { const struct pccard_product *pp; u_int32_t fcn = PCCARD_FUNCTION_UNSPEC; wlan_serialize_enter(); /* Make sure we're a network driver */ fcn = pccard_get_function_number(dev); if (fcn != PCCARD_FUNCTION_NETWORK) { wlan_serialize_exit(); return ENXIO; } pp = pccard_product_lookup(dev, wi_pccard_products, sizeof(wi_pccard_products[0]), NULL); if (pp != NULL) { if (pp->pp_name != NULL) device_set_desc(dev, pp->pp_name); wlan_serialize_exit(); return 0; } wlan_serialize_exit(); return ENXIO; }
static int ed_pccard_probe(device_t dev) { const struct ed_product *pp, *pp2; int error, first = 1; uint32_t fcn = PCCARD_FUNCTION_UNSPEC; /* Make sure we're a network function */ error = pccard_get_function(dev, &fcn); if (error != 0) return (error); if ((pp = (const struct ed_product *) pccard_product_lookup(dev, (const struct pccard_product *) ed_pccard_products, sizeof(ed_pccard_products[0]), NULL)) != NULL) { if (pp->prod.pp_name != NULL) device_set_desc(dev, pp->prod.pp_name); /* * Some devices don't ID themselves as network, but * that's OK if the flags say so. */ if (!(pp->flags & NE2000DVF_ANYFUNC) && fcn != PCCARD_FUNCTION_NETWORK) return (ENXIO); /* * Some devices match multiple entries. Report that * as a warning to help cull the table */ pp2 = pp; while ((pp2 = (const struct ed_product *)pccard_product_lookup( dev, (const struct pccard_product *)(pp2 + 1), sizeof(ed_pccard_products[0]), NULL)) != NULL) { if (first) { device_printf(dev, "Warning: card matches multiple entries. Report to [email protected]\n"); ed_pccard_print_entry(pp); first = 0; } ed_pccard_print_entry(pp2); } return (0); } return (ENXIO); }
static int fdc_pccard_probe(device_t dev) { if (pccard_product_lookup(dev, fdc_pccard_products, sizeof(fdc_pccard_products[0]), NULL) != NULL) { device_set_desc(dev, "PC Card Floppy"); return (0); } return (ENXIO); }
static int nsp_pccard_match(device_t dev) { const struct pccard_product *pp; if ((pp = pccard_product_lookup(dev, nsp_products, sizeof(nsp_products[0]), NULL)) != NULL) { device_set_desc(dev, pp->pp_name); return (0); } return (ENXIO); }
/* * Probe the pccard. */ static int snc_pccard_probe(device_t dev) { const struct pccard_product *pp; if ((pp = pccard_product_lookup(dev, snc_pccard_products, sizeof(snc_pccard_products[0]), NULL)) == NULL) return (EIO); if (pp->pp_name != NULL) device_set_desc(dev, pp->pp_name); return (0); }
/* * Probe for the card. */ static int cmx_pccard_probe(device_t dev) { const struct pccard_product *pp; if ((pp = pccard_product_lookup(dev, cmx_pccard_products, sizeof(cmx_pccard_products[0]), NULL)) != NULL) { if (pp->pp_name != NULL) device_set_desc(dev, pp->pp_name); return 0; } return EIO; }
static int an_pccard_probe(device_t dev) { const struct pccard_product *pp; if ((pp = pccard_product_lookup(dev, an_pccard_products, sizeof(an_pccard_products[0]), NULL)) != NULL) { if (pp->pp_name != NULL) device_set_desc(dev, pp->pp_name); return (0); } return (ENXIO); }
static int fe_pccard_match(device_t dev) { const struct pccard_product *pp; if ((pp = pccard_product_lookup(dev, (const struct pccard_product *)fe_pccard_products, sizeof(fe_pccard_products[0]), NULL)) != NULL) { device_set_desc(dev, pp->pp_name); return 0; } return EIO; }
static int bt3c_pccard_probe(device_t dev) { struct pccard_product const *pp = NULL; pp = pccard_product_lookup(dev, bt3c_pccard_products, sizeof(bt3c_pccard_products[0]), NULL); if (pp == NULL) return (ENXIO); device_set_desc(dev, pp->pp_name); return (0); } /* bt3c_pccard_probe */
static int aic_pccard_probe(device_t dev) { const struct pccard_product *pp; if ((pp = pccard_product_lookup(dev, aic_pccard_products, sizeof(aic_pccard_products[0]), NULL)) != NULL) { if (pp->pp_name != NULL) device_set_desc(dev, pp->pp_name); else device_set_desc(dev, "Adaptec 6260/6360 SCSI controller"); return (BUS_PROBE_DEFAULT); } return (ENXIO); }
static int bt3c_pccard_probe(device_t dev) { static struct pccard_product const bt3c_pccard_products[] = { PCMCIA_CARD(3COM, 3CRWB609), { NULL, } }; struct pccard_product const *pp = NULL; pp = pccard_product_lookup(dev, bt3c_pccard_products, sizeof(bt3c_pccard_products[0]), NULL); if (pp == NULL) return (ENXIO); device_set_desc(dev, pp->pp_name); return (0); } /* bt3c_pccard_probe */
static int cs_pccard_probe(device_t dev) { const struct pccard_product *pp; uint32_t fcn = PCCARD_FUNCTION_UNSPEC; /* Make sure we're a network function */ pccard_get_function(dev, &fcn); if (fcn != PCCARD_FUNCTION_NETWORK) return (ENXIO); if ((pp = pccard_product_lookup(dev, cs_pccard_products, sizeof(cs_pccard_products[0]), NULL)) != NULL) { if (pp->pp_name != NULL) device_set_desc(dev, pp->pp_name); return 0; } return EIO; }
static int ata_pccard_probe(device_t dev) { const struct pccard_product *pp; u_int32_t fcn = PCCARD_FUNCTION_UNSPEC; fcn = pccard_get_function_number(dev); /* if it says its a disk we should register it */ if (fcn == PCCARD_FUNCTION_DISK) return 0; /* match other devices here, primarily cdrom/dvd rom */ if ((pp = pccard_product_lookup(dev, ata_pccard_products, sizeof(ata_pccard_products[0]), NULL))) { if (pp->pp_name) device_set_desc(dev, pp->pp_name); return 0; } return ENXIO; }
static int wi_pccard_probe(device_t dev) { const struct pccard_product *pp; u_int32_t fcn = PCCARD_FUNCTION_UNSPEC; int error; /* Make sure we're a network driver */ error = pccard_get_function(dev, &fcn); if (error != 0) return error; if (fcn != PCCARD_FUNCTION_NETWORK) return ENXIO; pp = pccard_product_lookup(dev, wi_pccard_products, sizeof(wi_pccard_products[0]), NULL); if (pp != NULL) { if (pp->pp_name != NULL) device_set_desc(dev, pp->pp_name); return 0; } return ENXIO; }
static int fe_pccard_probe(device_t dev) { int error; uint32_t fcn = PCCARD_FUNCTION_UNSPEC; const struct fe_pccard_product *pp; int i; if ((pp = (const struct fe_pccard_product *)pccard_product_lookup(dev, (const struct pccard_product *)fe_pccard_products, sizeof(fe_pccard_products[0]), NULL)) != NULL) { if (pp->mpp_product.pp_name != NULL) device_set_desc(dev, pp->mpp_product.pp_name); if (pp->mpp_flags & MPP_ANYFUNC) return (0); /* Make sure we're a network function */ error = pccard_get_function(dev, &fcn); if (error != 0) return (error); if (fcn != PCCARD_FUNCTION_NETWORK) return (ENXIO); if (pp->mpp_flags & MPP_SKIP_TO_CFE) { for (i = pp->mpp_cfe; i < 32; i++) { if (pccard_select_cfe(dev, i) == 0) goto good; } device_printf(dev, "Failed to map CFE %d or higher\n", pp->mpp_cfe); return ENXIO; } good: ; return (0); } return (ENXIO); }
static int ex_pccard_probe(device_t dev) { const struct pccard_product *pp; int error, i, j; uint32_t fcn = PCCARD_FUNCTION_UNSPEC; if ((pp = pccard_product_lookup(dev, ex_pccard_products, sizeof(ex_pccard_products[0]), NULL)) == NULL) return (EIO); if (pp->pp_name != NULL) device_set_desc(dev, pp->pp_name); /* * Olicom 22.8k and 33.6k modems need to activate the right * CFE. The odd formula below replicates the sequence of cfes * that have multiple resources: * 9, 11, 13, 15, 0 + 9 * 25, 27, 29, 31, 16 + 9 * 41, 43, 45, 47, 32 + 9 * 57, 59, 61, 63 48 + 9 * (entries 8, 24, 40 and 56 are single resoruce cfes) * Fortunately the code that enables and disables the multiple * fuctions of the card won't mess with the lower bit for cards * that aren't stanards conforming MFC cards (which these olicom * cards aren't). * * Note: These cards still don't get interrupts for reasons * unknown, even when the right cfe is selected. There's likely * something in the CCR that needs to be manually tweaked, but * the COR bits seem to all be used. Bit 0 and 3 are always set * and the other bits select the config to use. Maybe one of those * two bits needs to be cleared, or there's something else in the * CCR that needs tweaking. The pattern of resources suggests * bit 0 turns on the ethernet, however... */ if (pp->pp_vendor == PCMCIA_VENDOR_OLICOM && (pp->pp_product == PCMCIA_PRODUCT_OLICOM_OC2231 || pp->pp_product == PCMCIA_PRODUCT_OLICOM_OC2232)) { if (pccard_select_cfe(dev, 1) == 0) goto good; for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { printf("Trying %d %d\n", i, j); if (pccard_select_cfe(dev, (i << 4) + (j << 1) + 9) == 0) goto good; } } /* Can't activate the net entries, punt */ return (EIO); } /* * All other cards supported by this driver don't need specail * treatment, so just filter based on the type of card. The * special treatment ones are setup to 'fail safe' to a modem so * this check would effectively filter them out as well. */ error = pccard_get_function(dev, &fcn); if (error != 0) return (error); if (fcn != PCCARD_FUNCTION_NETWORK) return (EIO); good:; return (0); }
static int ed_pccard_attach(device_t dev) { u_char sum; u_char enaddr[ETHER_ADDR_LEN]; const struct ed_product *pp; int error, i, flags, port_rid, modem_rid; struct ed_softc *sc = device_get_softc(dev); u_long size; static uint16_t *intr_vals[] = {NULL, NULL}; sc->dev = dev; if ((pp = (const struct ed_product *) pccard_product_lookup(dev, (const struct pccard_product *) ed_pccard_products, sizeof(ed_pccard_products[0]), NULL)) == NULL) { printf("Can't find\n"); return (ENXIO); } modem_rid = port_rid = -1; if (pp->flags & NE2000DVF_MODEM) { for (i = 0; i < 4; i++) { size = bus_get_resource_count(dev, SYS_RES_IOPORT, i); if (size == ED_NOVELL_IO_PORTS) port_rid = i; else if (size == 8) modem_rid = i; } if (port_rid == -1) { device_printf(dev, "Cannot locate my ports!\n"); return (ENXIO); } } else { port_rid = 0; } /* Allocate the port resource during setup. */ error = ed_alloc_port(dev, port_rid, ED_NOVELL_IO_PORTS); if (error) { printf("alloc_port failed\n"); return (error); } if (rman_get_size(sc->port_res) == ED_NOVELL_IO_PORTS / 2) { port_rid++; sc->port_res2 = bus_alloc_resource(dev, SYS_RES_IOPORT, &port_rid, 0ul, ~0ul, 1, RF_ACTIVE); if (sc->port_res2 == NULL || rman_get_size(sc->port_res2) != ED_NOVELL_IO_PORTS / 2) { error = ENXIO; goto bad; } } error = ed_alloc_irq(dev, 0, 0); if (error) goto bad; /* * Determine which chipset we are. Almost all the PC Card chipsets * have the Novel ASIC and NIC offsets. There's 2 known cards that * follow the WD80x3 conventions, which are handled as a special case. */ sc->asic_offset = ED_NOVELL_ASIC_OFFSET; sc->nic_offset = ED_NOVELL_NIC_OFFSET; error = ENXIO; flags = device_get_flags(dev); if (error != 0) error = ed_pccard_dl100xx(dev, pp); if (error != 0) error = ed_pccard_ax88x90(dev, pp); if (error != 0) error = ed_pccard_tc5299j(dev, pp); if (error != 0) { error = ed_probe_Novell_generic(dev, flags); printf("Novell generic probe failed: %d\n", error); } if (error != 0 && (pp->flags & NE2000DVF_TOSHIBA)) { flags |= ED_FLAGS_TOSH_ETHER; flags |= ED_FLAGS_PCCARD; sc->asic_offset = ED_WD_ASIC_OFFSET; sc->nic_offset = ED_WD_NIC_OFFSET; error = ed_probe_WD80x3_generic(dev, flags, intr_vals); } if (error) goto bad; /* * There are several ways to get the MAC address for the card. * Some of the above probe routines can fill in the enaddr. If * not, we run through a number of 'well known' locations: * (1) From the PC Card FUNCE * (2) From offset 0 in the shared memory * (3) From a hinted offset in attribute memory * (4) From 0xff0 in attribute memory * If we can't get a non-zero MAC address from this list, we fail. */ for (i = 0, sum = 0; i < ETHER_ADDR_LEN; i++) sum |= sc->enaddr[i]; if (sum == 0) { pccard_get_ether(dev, enaddr); if (bootverbose) device_printf(dev, "CIS MAC %6D\n", enaddr, ":"); for (i = 0, sum = 0; i < ETHER_ADDR_LEN; i++) sum |= enaddr[i]; if (sum == 0 && ed_pccard_rom_mac(dev, enaddr)) { if (bootverbose) device_printf(dev, "ROM mac %6D\n", enaddr, ":"); sum++; } if (sum == 0 && pp->flags & NE2000DVF_ENADDR) { for (i = 0; i < ETHER_ADDR_LEN; i++) { pccard_attr_read_1(dev, pp->enoff + i * 2, enaddr + i); sum |= enaddr[i]; } if (bootverbose) device_printf(dev, "Hint %x MAC %6D\n", pp->enoff, enaddr, ":"); } if (sum == 0) { for (i = 0; i < ETHER_ADDR_LEN; i++) { pccard_attr_read_1(dev, ED_DEFAULT_MAC_OFFSET + i * 2, enaddr + i); sum |= enaddr[i]; } if (bootverbose) device_printf(dev, "Fallback MAC %6D\n", enaddr, ":"); } if (sum == 0) { device_printf(dev, "Cannot extract MAC address.\n"); ed_release_resources(dev); return (ENXIO); } bcopy(enaddr, sc->enaddr, ETHER_ADDR_LEN); } error = ed_attach(dev); if (error) goto bad; if (sc->chip_type == ED_CHIP_TYPE_DL10019 || sc->chip_type == ED_CHIP_TYPE_DL10022) { /* Try to attach an MII bus, but ignore errors. */ ed_pccard_dl100xx_mii_reset(sc); (void)mii_attach(dev, &sc->miibus, sc->ifp, ed_ifmedia_upd, ed_ifmedia_sts, BMSR_DEFCAPMASK, MII_PHY_ANY, MII_OFFSET_ANY, MIIF_FORCEANEG); } else if (sc->chip_type == ED_CHIP_TYPE_AX88190 || sc->chip_type == ED_CHIP_TYPE_AX88790 || sc->chip_type == ED_CHIP_TYPE_TC5299J) { error = mii_attach(dev, &sc->miibus, sc->ifp, ed_ifmedia_upd, ed_ifmedia_sts, BMSR_DEFCAPMASK, MII_PHY_ANY, MII_OFFSET_ANY, MIIF_FORCEANEG); if (error != 0) { device_printf(dev, "attaching PHYs failed\n"); goto bad; } } if (sc->miibus != NULL) { sc->sc_tick = ed_pccard_tick; sc->sc_mediachg = ed_pccard_mediachg; sc->sc_media_ioctl = ed_pccard_media_ioctl; ed_pccard_kick_phy(sc); } else { ed_gen_ifmedia_init(sc); } if (modem_rid != -1) ed_pccard_add_modem(dev); error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET | INTR_MPSAFE, NULL, edintr, sc, &sc->irq_handle); if (error) { device_printf(dev, "setup intr failed %d \n", error); goto bad; } return (0); bad: ed_detach(dev); return (error); }