static int sis5595_setup(struct pci_dev *SIS5595_dev) { u16 a; u8 val; int *i; int retval; /* Look for imposters */ for (i = blacklist; *i != 0; i++) { struct pci_dev *dev; dev = pci_get_device(PCI_VENDOR_ID_SI, *i, NULL); if (dev) { dev_err(&SIS5595_dev->dev, "Looked for SIS5595 but found unsupported device %.4x\n", *i); pci_dev_put(dev); return -ENODEV; } } /* Determine the address of the SMBus areas */ pci_read_config_word(SIS5595_dev, ACPI_BASE, &sis5595_base); if (sis5595_base == 0 && force_addr == 0) { dev_err(&SIS5595_dev->dev, "ACPI base address uninitialized - upgrade BIOS or use force_addr=0xaddr\n"); return -ENODEV; } if (force_addr) sis5595_base = force_addr & ~(SIS5595_EXTENT - 1); dev_dbg(&SIS5595_dev->dev, "ACPI Base address: %04x\n", sis5595_base); /* NB: We grab just the two SMBus registers here, but this may still * interfere with ACPI :-( */ retval = acpi_check_region(sis5595_base + SMB_INDEX, 2, sis5595_driver.name); if (retval) return retval; if (!request_region(sis5595_base + SMB_INDEX, 2, sis5595_driver.name)) { dev_err(&SIS5595_dev->dev, "SMBus registers 0x%04x-0x%04x already in use!\n", sis5595_base + SMB_INDEX, sis5595_base + SMB_INDEX + 1); return -ENODEV; } if (force_addr) { dev_info(&SIS5595_dev->dev, "forcing ISA address 0x%04X\n", sis5595_base); if (pci_write_config_word(SIS5595_dev, ACPI_BASE, sis5595_base) != PCIBIOS_SUCCESSFUL) goto error; if (pci_read_config_word(SIS5595_dev, ACPI_BASE, &a) != PCIBIOS_SUCCESSFUL) goto error; if ((a & ~(SIS5595_EXTENT - 1)) != sis5595_base) { /* doesn't work for some chips! */ dev_err(&SIS5595_dev->dev, "force address failed - not supported?\n"); goto error; } } if (pci_read_config_byte(SIS5595_dev, SIS5595_ENABLE_REG, &val) != PCIBIOS_SUCCESSFUL) goto error; if ((val & 0x80) == 0) { dev_info(&SIS5595_dev->dev, "enabling ACPI\n"); if (pci_write_config_byte(SIS5595_dev, SIS5595_ENABLE_REG, val | 0x80) != PCIBIOS_SUCCESSFUL) goto error; if (pci_read_config_byte(SIS5595_dev, SIS5595_ENABLE_REG, &val) != PCIBIOS_SUCCESSFUL) goto error; if ((val & 0x80) == 0) { /* doesn't work for some chips? */ dev_err(&SIS5595_dev->dev, "ACPI enable failed - not supported?\n"); goto error; } } /* Everything is happy */ return 0; error: release_region(sis5595_base + SMB_INDEX, 2); return -ENODEV; }
static void ichss_identify(driver_t *driver, device_t parent) { device_t child; uint32_t pmbase; if (resource_disabled("ichss", 0)) return; /* * It appears that ICH SpeedStep only requires a single CPU to * set the value (since the chipset is shared by all CPUs.) * Thus, we only add a child to cpu 0. */ if (device_get_unit(parent) != 0) return; /* Avoid duplicates. */ if (device_find_child(parent, "ichss", -1)) return; /* * ICH2/3/4-M I/O Controller Hub is at bus 0, slot 1F, function 0. * E.g. see Section 6.1 "PCI Devices and Functions" and table 6.1 of * Intel(r) 82801BA I/O Controller Hub 2 (ICH2) and Intel(r) 82801BAM * I/O Controller Hub 2 Mobile (ICH2-M). */ ich_device = pci_find_bsf(0, 0x1f, 0); if (ich_device == NULL || pci_get_vendor(ich_device) != PCI_VENDOR_INTEL || (pci_get_device(ich_device) != PCI_DEV_82801BA && pci_get_device(ich_device) != PCI_DEV_82801CA && pci_get_device(ich_device) != PCI_DEV_82801DB)) return; /* * Certain systems with ICH2 and an Intel 82815_MC host bridge * where the host bridge's revision is < 5 lockup if SpeedStep * is used. */ if (pci_get_device(ich_device) == PCI_DEV_82801BA) { device_t hostb; hostb = pci_find_bsf(0, 0, 0); if (hostb != NULL && pci_get_vendor(hostb) == PCI_VENDOR_INTEL && pci_get_device(hostb) == PCI_DEV_82815_MC && pci_get_revid(hostb) < 5) return; } /* Find the PMBASE register from our PCI config header. */ pmbase = pci_read_config(ich_device, ICHSS_PMBASE_OFFSET, sizeof(pmbase)); if ((pmbase & ICHSS_IO_REG) == 0) { printf("ichss: invalid PMBASE memory type\n"); return; } pmbase &= ICHSS_PMBASE_MASK; if (pmbase == 0) { printf("ichss: invalid zero PMBASE address\n"); return; } DPRINT("ichss: PMBASE is %#x\n", pmbase); child = BUS_ADD_CHILD(parent, 20, "ichss", 0); if (child == NULL) { device_printf(parent, "add SpeedStep child failed\n"); return; } /* Add the bus master arbitration and control registers. */ bus_set_resource(child, SYS_RES_IOPORT, 0, pmbase + ICHSS_BM_OFFSET, 1); bus_set_resource(child, SYS_RES_IOPORT, 1, pmbase + ICHSS_CTRL_OFFSET, 1); }
static int sfxge_create(struct sfxge_softc *sc) { device_t dev; efx_nic_t *enp; int error; dev = sc->dev; sx_init(&sc->softc_lock, "sfxge_softc"); sc->stats_node = SYSCTL_ADD_NODE( device_get_sysctl_ctx(dev), SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "stats", CTLFLAG_RD, NULL, "Statistics"); if (!sc->stats_node) { error = ENOMEM; goto fail; } TASK_INIT(&sc->task_reset, 0, sfxge_reset, sc); (void) pci_enable_busmaster(dev); /* Initialize DMA mappings. */ if ((error = sfxge_dma_init(sc)) != 0) goto fail; /* Map the device registers. */ if ((error = sfxge_bar_init(sc)) != 0) goto fail; error = efx_family(pci_get_vendor(dev), pci_get_device(dev), &sc->family); KASSERT(error == 0, ("Family should be filtered by sfxge_probe()")); /* Create the common code nic object. */ mtx_init(&sc->enp_lock, "sfxge_nic", NULL, MTX_DEF); if ((error = efx_nic_create(sc->family, (efsys_identifier_t *)sc, &sc->bar, &sc->enp_lock, &enp)) != 0) goto fail3; sc->enp = enp; /* Initialize MCDI to talk to the microcontroller. */ if ((error = sfxge_mcdi_init(sc)) != 0) goto fail4; /* Probe the NIC and build the configuration data area. */ if ((error = efx_nic_probe(enp)) != 0) goto fail5; /* Initialize the NVRAM. */ if ((error = efx_nvram_init(enp)) != 0) goto fail6; /* Initialize the VPD. */ if ((error = efx_vpd_init(enp)) != 0) goto fail7; /* Reset the NIC. */ if ((error = efx_nic_reset(enp)) != 0) goto fail8; /* Initialize buffer table allocation. */ sc->buffer_table_next = 0; /* Set up interrupts. */ if ((error = sfxge_intr_init(sc)) != 0) goto fail8; /* Initialize event processing state. */ if ((error = sfxge_ev_init(sc)) != 0) goto fail11; /* Initialize receive state. */ if ((error = sfxge_rx_init(sc)) != 0) goto fail12; /* Initialize transmit state. */ if ((error = sfxge_tx_init(sc)) != 0) goto fail13; /* Initialize port state. */ if ((error = sfxge_port_init(sc)) != 0) goto fail14; sc->init_state = SFXGE_INITIALIZED; return (0); fail14: sfxge_tx_fini(sc); fail13: sfxge_rx_fini(sc); fail12: sfxge_ev_fini(sc); fail11: sfxge_intr_fini(sc); fail8: efx_vpd_fini(enp); fail7: efx_nvram_fini(enp); fail6: efx_nic_unprobe(enp); fail5: sfxge_mcdi_fini(sc); fail4: sc->enp = NULL; efx_nic_destroy(enp); mtx_destroy(&sc->enp_lock); fail3: sfxge_bar_fini(sc); (void) pci_disable_busmaster(sc->dev); fail: sc->dev = NULL; sx_destroy(&sc->softc_lock); return (error); }
/* called during probe() after chip reset completes */ static int ehci_pci_setup(struct usb_hcd *hcd) { struct ehci_hcd *ehci = hcd_to_ehci(hcd); struct pci_dev *pdev = to_pci_dev(hcd->self.controller); struct pci_dev *p_smbus; u8 rev; u32 temp; int retval; switch (pdev->vendor) { case PCI_VENDOR_ID_TOSHIBA_2: /* celleb's companion chip */ if (pdev->device == 0x01b5) { #ifdef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO ehci->big_endian_mmio = 1; #else ehci_warn(ehci, "unsupported big endian Toshiba quirk\n"); #endif } break; case PCI_VENDOR_ID_NETLOGIC: if (pdev->device == 0x1007) { #ifdef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO ehci->big_endian_mmio = 1; #else ehci->big_endian_mmio = 0; #endif } break; } ehci->caps = hcd->regs; ehci->regs = hcd->regs + HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); dbg_hcs_params(ehci, "reset"); dbg_hcc_params(ehci, "reset"); /* ehci_init() causes memory for DMA transfers to be * allocated. Thus, any vendor-specific workarounds based on * limiting the type of memory used for DMA transfers must * happen before ehci_init() is called. */ switch (pdev->vendor) { case PCI_VENDOR_ID_NVIDIA: /* NVidia reports that certain chips don't handle * QH, ITD, or SITD addresses above 2GB. (But TD, * data buffer, and periodic schedule are normal.) */ switch (pdev->device) { case 0x003c: /* MCP04 */ case 0x005b: /* CK804 */ case 0x00d8: /* CK8 */ case 0x00e8: /* CK8S */ if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(31)) < 0) ehci_warn(ehci, "can't enable NVidia " "workaround for >2GB RAM\n"); break; } break; } /* cache this readonly data; minimize chip reads */ ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); retval = ehci_halt(ehci); if (retval) return retval; /* data structure init */ retval = ehci_init(hcd); if (retval) return retval; switch (pdev->vendor) { case PCI_VENDOR_ID_INTEL: ehci->need_io_watchdog = 0; if (pdev->device == 0x27cc) { ehci->broken_periodic = 1; ehci_info(ehci, "using broken periodic workaround\n"); } break; case PCI_VENDOR_ID_TDI: if (pdev->device == PCI_DEVICE_ID_TDI_EHCI) { hcd->has_tt = 1; tdi_reset(ehci); } break; case PCI_VENDOR_ID_AMD: /* AMD8111 EHCI doesn't work, according to AMD errata */ if (pdev->device == 0x7463) { ehci_info(ehci, "ignoring AMD8111 (errata)\n"); retval = -EIO; goto done; } break; case PCI_VENDOR_ID_NVIDIA: switch (pdev->device) { /* Some NForce2 chips have problems with selective suspend; * fixed in newer silicon. */ case 0x0068: if (pdev->revision < 0xa4) ehci->no_selective_suspend = 1; break; } break; case PCI_VENDOR_ID_VIA: if (pdev->device == 0x3104 && (pdev->revision & 0xf0) == 0x60) { u8 tmp; /* The VT6212 defaults to a 1 usec EHCI sleep time which * hogs the PCI bus *badly*. Setting bit 5 of 0x4B makes * that sleep time use the conventional 10 usec. */ pci_read_config_byte(pdev, 0x4b, &tmp); if (tmp & 0x20) break; pci_write_config_byte(pdev, 0x4b, tmp | 0x20); } break; case PCI_VENDOR_ID_ATI: /* SB600 and old version of SB700 have a bug in EHCI controller, * which causes usb devices lose response in some cases. */ if ((pdev->device == 0x4386) || (pdev->device == 0x4396)) { p_smbus = pci_get_device(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_SBX00_SMBUS, NULL); if (!p_smbus) break; rev = p_smbus->revision; if ((pdev->device == 0x4386) || (rev == 0x3a) || (rev == 0x3b)) { u8 tmp; ehci_info(ehci, "applying AMD SB600/SB700 USB " "freeze workaround\n"); pci_read_config_byte(pdev, 0x53, &tmp); pci_write_config_byte(pdev, 0x53, tmp | (1<<3)); } pci_dev_put(p_smbus); } break; } /* optional debug port, normally in the first BAR */ temp = pci_find_capability(pdev, 0x0a); if (temp) { pci_read_config_dword(pdev, temp, &temp); temp >>= 16; if ((temp & (3 << 13)) == (1 << 13)) { temp &= 0x1fff; ehci->debug = ehci_to_hcd(ehci)->regs + temp; temp = ehci_readl(ehci, &ehci->debug->control); ehci_info(ehci, "debug port %d%s\n", HCS_DEBUG_PORT(ehci->hcs_params), (temp & DBGP_ENABLED) ? " IN USE" : ""); if (!(temp & DBGP_ENABLED)) ehci->debug = NULL; } } ehci_reset(ehci); /* at least the Genesys GL880S needs fixup here */ temp = HCS_N_CC(ehci->hcs_params) * HCS_N_PCC(ehci->hcs_params); temp &= 0x0f; if (temp && HCS_N_PORTS(ehci->hcs_params) > temp) { ehci_dbg(ehci, "bogus port configuration: " "cc=%d x pcc=%d < ports=%d\n", HCS_N_CC(ehci->hcs_params), HCS_N_PCC(ehci->hcs_params), HCS_N_PORTS(ehci->hcs_params)); switch (pdev->vendor) { case 0x17a0: /* GENESYS */ /* GL880S: should be PORTS=2 */ temp |= (ehci->hcs_params & ~0xf); ehci->hcs_params = temp; break; case PCI_VENDOR_ID_NVIDIA: /* NF4: should be PCC=10 */ break; } } /* Serial Bus Release Number is at PCI 0x60 offset */ pci_read_config_byte(pdev, 0x60, &ehci->sbrn); /* Keep this around for a while just in case some EHCI * implementation uses legacy PCI PM support. This test * can be removed on 17 Dec 2009 if the dev_warn() hasn't * been triggered by then. */ if (!device_can_wakeup(&pdev->dev)) { u16 port_wake; pci_read_config_word(pdev, 0x62, &port_wake); if (port_wake & 0x0001) { dev_warn(&pdev->dev, "Enabling legacy PCI PM\n"); device_set_wakeup_capable(&pdev->dev, 1); } } #ifdef CONFIG_USB_SUSPEND /* REVISIT: the controller works fine for wakeup iff the root hub * itself is "globally" suspended, but usbcore currently doesn't * understand such things. * * System suspend currently expects to be able to suspend the entire * device tree, device-at-a-time. If we failed selective suspend * reports, system suspend would fail; so the root hub code must claim * success. That's lying to usbcore, and it matters for runtime * PM scenarios with selective suspend and remote wakeup... */ if (ehci->no_selective_suspend && device_can_wakeup(&pdev->dev)) ehci_warn(ehci, "selective suspend/wakeup unavailable\n"); #endif ehci_port_power(ehci, 1); retval = ehci_pci_reinit(ehci, pdev); done: return retval; }
static int hpt_attach(device_t dev) { PHBA hba = (PHBA)device_get_softc(dev); HIM *him = hba->ldm_adapter.him; PCI_ID pci_id; HPT_UINT size; PVBUS vbus; PVBUS_EXT vbus_ext; KdPrint(("hpt_attach(%d/%d/%d)", pci_get_bus(dev), pci_get_slot(dev), pci_get_function(dev))); #if __FreeBSD_version >=440000 pci_enable_busmaster(dev); #endif pci_id.vid = pci_get_vendor(dev); pci_id.did = pci_get_device(dev); pci_id.rev = pci_get_revid(dev); pci_id.subsys = (HPT_U32)(pci_get_subdevice(dev)) << 16 | pci_get_subvendor(dev); size = him->get_adapter_size(&pci_id); hba->ldm_adapter.him_handle = malloc(size, M_DEVBUF, M_WAITOK); if (!hba->ldm_adapter.him_handle) return ENXIO; hba->pcidev = dev; hba->pciaddr.tree = 0; hba->pciaddr.bus = pci_get_bus(dev); hba->pciaddr.device = pci_get_slot(dev); hba->pciaddr.function = pci_get_function(dev); if (!him->create_adapter(&pci_id, hba->pciaddr, hba->ldm_adapter.him_handle, hba)) { free(hba->ldm_adapter.him_handle, M_DEVBUF); return -1; } os_printk("adapter at PCI %d:%d:%d, IRQ %d", hba->pciaddr.bus, hba->pciaddr.device, hba->pciaddr.function, pci_get_irq(dev)); if (!ldm_register_adapter(&hba->ldm_adapter)) { size = ldm_get_vbus_size(); vbus_ext = malloc(sizeof(VBUS_EXT) + size, M_DEVBUF, M_WAITOK); if (!vbus_ext) { free(hba->ldm_adapter.him_handle, M_DEVBUF); return -1; } memset(vbus_ext, 0, sizeof(VBUS_EXT)); vbus_ext->ext_type = EXT_TYPE_VBUS; ldm_create_vbus((PVBUS)vbus_ext->vbus, vbus_ext); ldm_register_adapter(&hba->ldm_adapter); } ldm_for_each_vbus(vbus, vbus_ext) { if (hba->ldm_adapter.vbus==vbus) { hba->vbus_ext = vbus_ext; hba->next = vbus_ext->hba_list; vbus_ext->hba_list = hba; break; } } return 0; }
/* * We try to avoid enabling the hardware if it's not * there, but we don't know how to test. But we do know * that the PC110 is not a PCI system. So if we find any * PCI devices in the machine, we don't have a PC110. */ static int __init pc110pad_init(void) { struct pci_dev *dev; int err; dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL); if (dev) { pci_dev_put(dev); return -ENODEV; } if (!request_region(pc110pad_io, 4, "pc110pad")) { printk(KERN_ERR "pc110pad: I/O area %#x-%#x in use.\n", pc110pad_io, pc110pad_io + 4); return -EBUSY; } outb(PC110PAD_OFF, pc110pad_io + 2); if (request_irq(pc110pad_irq, pc110pad_interrupt, 0, "pc110pad", NULL)) { printk(KERN_ERR "pc110pad: Unable to get irq %d.\n", pc110pad_irq); err = -EBUSY; goto err_release_region; } pc110pad_dev = input_allocate_device(); if (!pc110pad_dev) { printk(KERN_ERR "pc110pad: Not enough memory.\n"); err = -ENOMEM; goto err_free_irq; } pc110pad_dev->name = "IBM PC110 TouchPad"; pc110pad_dev->phys = "isa15e0/input0"; pc110pad_dev->id.bustype = BUS_ISA; pc110pad_dev->id.vendor = 0x0003; pc110pad_dev->id.product = 0x0001; pc110pad_dev->id.version = 0x0100; pc110pad_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); pc110pad_dev->absbit[0] = BIT(ABS_X) | BIT(ABS_Y); pc110pad_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); pc110pad_dev->absmax[ABS_X] = 0x1ff; pc110pad_dev->absmax[ABS_Y] = 0x0ff; pc110pad_dev->open = pc110pad_open; pc110pad_dev->close = pc110pad_close; err = input_register_device(pc110pad_dev); if (err) goto err_free_dev; return 0; err_free_dev: input_free_device(pc110pad_dev); err_free_irq: free_irq(pc110pad_irq, NULL); err_release_region: release_region(pc110pad_io, 4); return err; }
static int mlx_pci_attach(device_t dev) { struct mlx_softc *sc; int i, error; u_int32_t command; debug_called(1); /* * Make sure we are going to be able to talk to this board. */ command = pci_read_config(dev, PCIR_COMMAND, 2); if ((command & PCIM_CMD_MEMEN) == 0) { device_printf(dev, "memory window not available\n"); return(ENXIO); } /* force the busmaster enable bit on */ command |= PCIM_CMD_BUSMASTEREN; pci_write_config(dev, PCIR_COMMAND, command, 2); /* * Initialise softc. */ sc = device_get_softc(dev); bzero(sc, sizeof(*sc)); sc->mlx_dev = dev; /* * Work out what sort of adapter this is (we need to know this in order * to map the appropriate interface resources). */ sc->mlx_iftype = 0; for (i = 0; mlx_identifiers[i].vendor != 0; i++) { if ((mlx_identifiers[i].vendor == pci_get_vendor(dev)) && (mlx_identifiers[i].device == pci_get_device(dev))) { sc->mlx_iftype = mlx_identifiers[i].iftype; break; } } if (sc->mlx_iftype == 0) /* shouldn't happen */ return(ENXIO); /* * Allocate the PCI register window. */ /* type 2/3 adapters have an I/O region we don't prefer at base 0 */ switch(sc->mlx_iftype) { case MLX_IFTYPE_2: case MLX_IFTYPE_3: sc->mlx_mem_type = SYS_RES_MEMORY; sc->mlx_mem_rid = MLX_CFG_BASE1; sc->mlx_mem = bus_alloc_resource_any(dev, sc->mlx_mem_type, &sc->mlx_mem_rid, RF_ACTIVE); if (sc->mlx_mem == NULL) { sc->mlx_mem_type = SYS_RES_IOPORT; sc->mlx_mem_rid = MLX_CFG_BASE0; sc->mlx_mem = bus_alloc_resource_any(dev, sc->mlx_mem_type, &sc->mlx_mem_rid, RF_ACTIVE); } break; case MLX_IFTYPE_4: case MLX_IFTYPE_5: sc->mlx_mem_type = SYS_RES_MEMORY; sc->mlx_mem_rid = MLX_CFG_BASE0; sc->mlx_mem = bus_alloc_resource_any(dev, sc->mlx_mem_type, &sc->mlx_mem_rid, RF_ACTIVE); break; } if (sc->mlx_mem == NULL) { device_printf(sc->mlx_dev, "couldn't allocate mailbox window\n"); mlx_free(sc); return(ENXIO); } sc->mlx_btag = rman_get_bustag(sc->mlx_mem); sc->mlx_bhandle = rman_get_bushandle(sc->mlx_mem); /* * Allocate the parent bus DMA tag appropriate for PCI. */ error = bus_dma_tag_create(NULL, /* parent */ 1, 0, /* alignment, boundary */ BUS_SPACE_MAXADDR_32BIT, /* lowaddr */ BUS_SPACE_MAXADDR, /* highaddr */ NULL, NULL, /* filter, filterarg */ MAXBSIZE, MLX_NSEG, /* maxsize, nsegments */ BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */ BUS_DMA_ALLOCNOW, /* flags */ NULL, /* lockfunc */ NULL, /* lockarg */ &sc->mlx_parent_dmat); if (error != 0) { device_printf(dev, "can't allocate parent DMA tag\n"); mlx_free(sc); return(ENOMEM); } /* * Do bus-independant initialisation. */ error = mlx_attach(sc); if (error != 0) { mlx_free(sc); return(error); } /* * Start the controller. */ mlx_startup(sc); return(0); }
static int falcon_probe_nic(struct efx_nic *efx) { struct falcon_nic_data *nic_data; struct falcon_board *board; int rc; /* Allocate storage for hardware specific data */ nic_data = kzalloc(sizeof(*nic_data), GFP_KERNEL); if (!nic_data) return -ENOMEM; efx->nic_data = nic_data; rc = -ENODEV; if (efx_nic_fpga_ver(efx) != 0) { netif_err(efx, probe, efx->net_dev, "Falcon FPGA not supported\n"); goto fail1; } if (efx_nic_rev(efx) <= EFX_REV_FALCON_A1) { efx_oword_t nic_stat; struct pci_dev *dev; u8 pci_rev = efx->pci_dev->revision; if ((pci_rev == 0xff) || (pci_rev == 0)) { netif_err(efx, probe, efx->net_dev, "Falcon rev A0 not supported\n"); goto fail1; } efx_reado(efx, &nic_stat, FR_AB_NIC_STAT); if (EFX_OWORD_FIELD(nic_stat, FRF_AB_STRAP_10G) == 0) { netif_err(efx, probe, efx->net_dev, "Falcon rev A1 1G not supported\n"); goto fail1; } if (EFX_OWORD_FIELD(nic_stat, FRF_AA_STRAP_PCIE) == 0) { netif_err(efx, probe, efx->net_dev, "Falcon rev A1 PCI-X not supported\n"); goto fail1; } dev = pci_dev_get(efx->pci_dev); while ((dev = pci_get_device(EFX_VENDID_SFC, FALCON_A_S_DEVID, dev))) { if (dev->bus == efx->pci_dev->bus && dev->devfn == efx->pci_dev->devfn + 1) { nic_data->pci_dev2 = dev; break; } } if (!nic_data->pci_dev2) { netif_err(efx, probe, efx->net_dev, "failed to find secondary function\n"); rc = -ENODEV; goto fail2; } } /* Now we can reset the NIC */ rc = __falcon_reset_hw(efx, RESET_TYPE_ALL); if (rc) { netif_err(efx, probe, efx->net_dev, "failed to reset NIC\n"); goto fail3; } /* Allocate memory for INT_KER */ rc = efx_nic_alloc_buffer(efx, &efx->irq_status, sizeof(efx_oword_t)); if (rc) goto fail4; BUG_ON(efx->irq_status.dma_addr & 0x0f); netif_dbg(efx, probe, efx->net_dev, "INT_KER at %llx (virt %p phys %llx)\n", (u64)efx->irq_status.dma_addr, efx->irq_status.addr, (u64)virt_to_phys(efx->irq_status.addr)); falcon_probe_spi_devices(efx); /* Read in the non-volatile configuration */ rc = falcon_probe_nvconfig(efx); if (rc) { if (rc == -EINVAL) netif_err(efx, probe, efx->net_dev, "NVRAM is invalid\n"); goto fail5; } /* Initialise I2C adapter */ board = falcon_board(efx); board->i2c_adap.owner = THIS_MODULE; board->i2c_data = falcon_i2c_bit_operations; board->i2c_data.data = efx; board->i2c_adap.algo_data = &board->i2c_data; board->i2c_adap.dev.parent = &efx->pci_dev->dev; strlcpy(board->i2c_adap.name, "SFC4000 GPIO", sizeof(board->i2c_adap.name)); rc = i2c_bit_add_bus(&board->i2c_adap); if (rc) goto fail5; rc = falcon_board(efx)->type->init(efx); if (rc) { netif_err(efx, probe, efx->net_dev, "failed to initialise board\n"); goto fail6; } nic_data->stats_disable_count = 1; setup_timer(&nic_data->stats_timer, &falcon_stats_timer_func, (unsigned long)efx); return 0; fail6: BUG_ON(i2c_del_adapter(&board->i2c_adap)); memset(&board->i2c_adap, 0, sizeof(board->i2c_adap)); fail5: efx_nic_free_buffer(efx, &efx->irq_status); fail4: fail3: if (nic_data->pci_dev2) { pci_dev_put(nic_data->pci_dev2); nic_data->pci_dev2 = NULL; } fail2: fail1: kfree(efx->nic_data); return rc; }
static int ehci_pci_attach(device_t self) { ehci_softc_t *sc = device_get_softc(self); int err; int rid; /* initialise some bus fields */ sc->sc_bus.parent = self; sc->sc_bus.devices = sc->sc_devices; sc->sc_bus.devices_max = EHCI_MAX_DEVICES; /* get all DMA memory */ if (usb_bus_mem_alloc_all(&sc->sc_bus, USB_GET_DMA_TAG(self), &ehci_iterate_hw_softc)) { return (ENOMEM); } pci_enable_busmaster(self); switch (pci_read_config(self, PCI_USBREV, 1) & PCI_USB_REV_MASK) { case PCI_USB_REV_PRE_1_0: case PCI_USB_REV_1_0: case PCI_USB_REV_1_1: /* * NOTE: some EHCI USB controllers have the wrong USB * revision number. It appears those controllers are * fully compliant so we just ignore this value in * some common cases. */ device_printf(self, "pre-2.0 USB revision (ignored)\n"); /* fallthrough */ case PCI_USB_REV_2_0: break; default: /* Quirk for Parallels Desktop 4.0 */ device_printf(self, "USB revision is unknown. Assuming v2.0.\n"); break; } rid = PCI_CBMEM; sc->sc_io_res = bus_alloc_resource_any(self, SYS_RES_MEMORY, &rid, RF_ACTIVE); if (!sc->sc_io_res) { device_printf(self, "Could not map memory\n"); goto error; } sc->sc_io_tag = rman_get_bustag(sc->sc_io_res); sc->sc_io_hdl = rman_get_bushandle(sc->sc_io_res); sc->sc_io_size = rman_get_size(sc->sc_io_res); rid = 0; sc->sc_irq_res = bus_alloc_resource_any(self, SYS_RES_IRQ, &rid, RF_SHAREABLE | RF_ACTIVE); if (sc->sc_irq_res == NULL) { device_printf(self, "Could not allocate irq\n"); goto error; } sc->sc_bus.bdev = device_add_child(self, "usbus", -1); if (!sc->sc_bus.bdev) { device_printf(self, "Could not add USB device\n"); goto error; } device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus); /* * ehci_pci_match will never return NULL if ehci_pci_probe * succeeded */ device_set_desc(sc->sc_bus.bdev, ehci_pci_match(self)); switch (pci_get_vendor(self)) { case PCI_EHCI_VENDORID_ACERLABS: sprintf(sc->sc_vendor, "AcerLabs"); break; case PCI_EHCI_VENDORID_AMD: sprintf(sc->sc_vendor, "AMD"); break; case PCI_EHCI_VENDORID_APPLE: sprintf(sc->sc_vendor, "Apple"); break; case PCI_EHCI_VENDORID_ATI: sprintf(sc->sc_vendor, "ATI"); break; case PCI_EHCI_VENDORID_CMDTECH: sprintf(sc->sc_vendor, "CMDTECH"); break; case PCI_EHCI_VENDORID_INTEL: sprintf(sc->sc_vendor, "Intel"); break; case PCI_EHCI_VENDORID_NEC: sprintf(sc->sc_vendor, "NEC"); break; case PCI_EHCI_VENDORID_OPTI: sprintf(sc->sc_vendor, "OPTi"); break; case PCI_EHCI_VENDORID_PHILIPS: sprintf(sc->sc_vendor, "Philips"); break; case PCI_EHCI_VENDORID_SIS: sprintf(sc->sc_vendor, "SiS"); break; case PCI_EHCI_VENDORID_NVIDIA: case PCI_EHCI_VENDORID_NVIDIA2: sprintf(sc->sc_vendor, "nVidia"); break; case PCI_EHCI_VENDORID_VIA: sprintf(sc->sc_vendor, "VIA"); break; default: if (bootverbose) device_printf(self, "(New EHCI DeviceId=0x%08x)\n", pci_get_devid(self)); sprintf(sc->sc_vendor, "(0x%04x)", pci_get_vendor(self)); } #if (__FreeBSD_version >= 700031) err = bus_setup_intr(self, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE, NULL, (driver_intr_t *)ehci_interrupt, sc, &sc->sc_intr_hdl); #else err = bus_setup_intr(self, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE, (driver_intr_t *)ehci_interrupt, sc, &sc->sc_intr_hdl); #endif if (err) { device_printf(self, "Could not setup irq, %d\n", err); sc->sc_intr_hdl = NULL; goto error; } ehci_pci_take_controller(self); /* Undocumented quirks taken from Linux */ switch (pci_get_vendor(self)) { case PCI_EHCI_VENDORID_ATI: /* SB600 and SB700 EHCI quirk */ switch (pci_get_device(self)) { case 0x4386: ehci_pci_ati_quirk(self, 0); break; case 0x4396: ehci_pci_ati_quirk(self, 1); break; default: break; } break; case PCI_EHCI_VENDORID_VIA: ehci_pci_via_quirk(self); break; default: break; } /* Dropped interrupts workaround */ switch (pci_get_vendor(self)) { case PCI_EHCI_VENDORID_ATI: case PCI_EHCI_VENDORID_VIA: sc->sc_flags |= EHCI_SCFLG_LOSTINTRBUG; if (bootverbose) device_printf(self, "Dropped interrupts workaround enabled\n"); break; default: break; } /* Doorbell feature workaround */ switch (pci_get_vendor(self)) { case PCI_EHCI_VENDORID_NVIDIA: case PCI_EHCI_VENDORID_NVIDIA2: sc->sc_flags |= EHCI_SCFLG_IAADBUG; if (bootverbose) device_printf(self, "Doorbell workaround enabled\n"); break; default: break; } err = ehci_init(sc); if (!err) { err = device_probe_and_attach(sc->sc_bus.bdev); } if (err) { device_printf(self, "USB init failed err=%d\n", err); goto error; } return (0); error: ehci_pci_detach(self); return (ENXIO); }
static int mpt_pci_attach(device_t dev) { struct mpt_softc *mpt; int iqd; uint32_t val; int mpt_io_bar, mpt_mem_bar; mpt = (struct mpt_softc*)device_get_softc(dev); switch (pci_get_device(dev)) { case MPI_MANUFACTPAGE_DEVICEID_FC909_FB: case MPI_MANUFACTPAGE_DEVICEID_FC909: case MPI_MANUFACTPAGE_DEVICEID_FC919: case MPI_MANUFACTPAGE_DEVICEID_FC919_LAN_FB: case MPI_MANUFACTPAGE_DEVICEID_FC929: case MPI_MANUFACTPAGE_DEVICEID_FC929_LAN_FB: case MPI_MANUFACTPAGE_DEVICEID_FC929X: case MPI_MANUFACTPAGE_DEVICEID_FC929X_LAN_FB: case MPI_MANUFACTPAGE_DEVICEID_FC919X: case MPI_MANUFACTPAGE_DEVICEID_FC919X_LAN_FB: case MPI_MANUFACTPAGE_DEVICEID_FC949E: case MPI_MANUFACTPAGE_DEVICEID_FC949X: mpt->is_fc = 1; break; case MPI_MANUFACTPAGE_DEVID_SAS1078: case MPI_MANUFACTPAGE_DEVID_SAS1078DE_FB: mpt->is_1078 = 1; /* FALLTHROUGH */ case MPI_MANUFACTPAGE_DEVID_SAS1064: case MPI_MANUFACTPAGE_DEVID_SAS1064A: case MPI_MANUFACTPAGE_DEVID_SAS1064E: case MPI_MANUFACTPAGE_DEVID_SAS1066: case MPI_MANUFACTPAGE_DEVID_SAS1066E: case MPI_MANUFACTPAGE_DEVID_SAS1068: case MPI_MANUFACTPAGE_DEVID_SAS1068A_FB: case MPI_MANUFACTPAGE_DEVID_SAS1068E: case MPI_MANUFACTPAGE_DEVID_SAS1068E_FB: mpt->is_sas = 1; break; default: mpt->is_spi = 1; break; } mpt->dev = dev; mpt->unit = device_get_unit(dev); mpt->raid_resync_rate = MPT_RAID_RESYNC_RATE_DEFAULT; mpt->raid_mwce_setting = MPT_RAID_MWCE_DEFAULT; mpt->raid_queue_depth = MPT_RAID_QUEUE_DEPTH_DEFAULT; mpt->verbose = MPT_PRT_NONE; mpt->role = MPT_ROLE_NONE; mpt->mpt_ini_id = MPT_INI_ID_NONE; #ifdef __sparc64__ if (mpt->is_spi) mpt->mpt_ini_id = OF_getscsinitid(dev); #endif mpt_set_options(mpt); if (mpt->verbose == MPT_PRT_NONE) { mpt->verbose = MPT_PRT_WARN; /* Print INFO level (if any) if bootverbose is set */ mpt->verbose += (bootverbose != 0)? 1 : 0; } /* * Make sure that SERR, PERR, WRITE INVALIDATE and BUSMASTER are set. */ val = pci_read_config(dev, PCIR_COMMAND, 2); val |= PCIM_CMD_SERRESPEN | PCIM_CMD_PERRESPEN | PCIM_CMD_BUSMASTEREN | PCIM_CMD_MWRICEN; pci_write_config(dev, PCIR_COMMAND, val, 2); /* * Make sure we've disabled the ROM. */ val = pci_read_config(dev, PCIR_BIOS, 4); val &= ~PCIM_BIOS_ENABLE; pci_write_config(dev, PCIR_BIOS, val, 4); #if 0 /* * Is this part a dual? * If so, link with our partner (around yet) */ switch (pci_get_device(dev)) { case MPI_MANUFACTPAGE_DEVICEID_FC929: case MPI_MANUFACTPAGE_DEVICEID_FC929_LAN_FB: case MPI_MANUFACTPAGE_DEVICEID_FC949E: case MPI_MANUFACTPAGE_DEVICEID_FC949X: case MPI_MANUFACTPAGE_DEVID_53C1030: case MPI_MANUFACTPAGE_DEVID_53C1030ZC: mpt_link_peer(mpt); break; default: break; } #endif /* * Figure out which are the I/O and MEM Bars */ val = pci_read_config(dev, PCIR_BAR(0), 4); if (PCI_BAR_IO(val)) { /* BAR0 is IO, BAR1 is memory */ mpt_io_bar = 0; mpt_mem_bar = 1; } else { /* BAR0 is memory, BAR1 is IO */ mpt_mem_bar = 0; mpt_io_bar = 1; } /* * Set up register access. PIO mode is required for * certain reset operations (but must be disabled for * some cards otherwise). */ mpt_io_bar = PCIR_BAR(mpt_io_bar); mpt->pci_pio_reg = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &mpt_io_bar, RF_ACTIVE); if (mpt->pci_pio_reg == NULL) { if (bootverbose) { device_printf(dev, "unable to map registers in PIO mode\n"); } } else { mpt->pci_pio_st = rman_get_bustag(mpt->pci_pio_reg); mpt->pci_pio_sh = rman_get_bushandle(mpt->pci_pio_reg); } mpt_mem_bar = PCIR_BAR(mpt_mem_bar); mpt->pci_reg = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &mpt_mem_bar, RF_ACTIVE); if (mpt->pci_reg == NULL) { if (bootverbose || mpt->is_sas || mpt->pci_pio_reg == NULL) { device_printf(dev, "Unable to memory map registers.\n"); } if (mpt->is_sas || mpt->pci_pio_reg == NULL) { device_printf(dev, "Giving Up.\n"); goto bad; } if (bootverbose) { device_printf(dev, "Falling back to PIO mode.\n"); } mpt->pci_st = mpt->pci_pio_st; mpt->pci_sh = mpt->pci_pio_sh; } else { mpt->pci_st = rman_get_bustag(mpt->pci_reg); mpt->pci_sh = rman_get_bushandle(mpt->pci_reg); } /* Get a handle to the interrupt */ iqd = 0; if (mpt->msi_enable) { /* * First try to alloc an MSI-X message. If that * fails, then try to alloc an MSI message instead. */ val = 1; if (pci_alloc_msix(dev, &val) == 0) iqd = 1; val = 1; if (iqd == 0 && pci_alloc_msi(dev, &val) == 0) iqd = 1; } mpt->pci_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &iqd, RF_ACTIVE | (iqd != 0 ? 0 : RF_SHAREABLE)); if (mpt->pci_irq == NULL) { device_printf(dev, "could not allocate interrupt\n"); goto bad; } MPT_LOCK_SETUP(mpt); /* Disable interrupts at the part */ mpt_disable_ints(mpt); /* Register the interrupt handler */ if (bus_setup_intr(dev, mpt->pci_irq, MPT_IFLAGS, NULL, mpt_pci_intr, mpt, &mpt->ih)) { device_printf(dev, "could not setup interrupt\n"); goto bad; } /* Allocate dma memory */ if (mpt_dma_mem_alloc(mpt)) { mpt_prt(mpt, "Could not allocate DMA memory\n"); goto bad; } #if 0 /* * Save the PCI config register values * * Hard resets are known to screw up the BAR for diagnostic * memory accesses (Mem1). * * Using Mem1 is known to make the chip stop responding to * configuration space transfers, so we need to save it now */ mpt_read_config_regs(mpt); #endif /* * Disable PIO until we need it */ if (mpt->is_sas) { pci_disable_io(dev, SYS_RES_IOPORT); } /* Initialize the hardware */ if (mpt->disabled == 0) { if (mpt_attach(mpt) != 0) { goto bad; } } else { mpt_prt(mpt, "device disabled at user request\n"); goto bad; } mpt->eh = EVENTHANDLER_REGISTER(shutdown_post_sync, mpt_pci_shutdown, dev, SHUTDOWN_PRI_LAST); if (mpt->eh == NULL) { mpt_prt(mpt, "shutdown event registration failed\n"); mpt_disable_ints(mpt); (void) mpt_detach(mpt); mpt_reset(mpt, /*reinit*/FALSE); mpt_raid_free_mem(mpt); goto bad; } return (0); bad: mpt_dma_mem_free(mpt); mpt_free_bus_resources(mpt); #if 0 mpt_unlink_peer(mpt); #endif MPT_LOCK_DESTROY(mpt); /* * but return zero to preserve unit numbering */ return (0); }
static int agp_nvidia_attach (device_t dev) { struct agp_nvidia_softc *sc = device_get_softc(dev); struct agp_gatt *gatt; u_int32_t apbase; u_int32_t aplimit; u_int32_t temp; int size; int i; int error; switch (pci_get_device(dev)) { case NVIDIA_DEVICEID_NFORCE: sc->wbc_mask = 0x00010000; break; case NVIDIA_DEVICEID_NFORCE2: sc->wbc_mask = 0x80000000; break; default: device_printf(dev, "Bad chip id\n"); return (ENODEV); } /* AGP Controller */ sc->dev = dev; /* Memory Controller 1 */ sc->mc1_dev = pci_find_bsf(pci_get_bus(dev), 0, 1); if (sc->mc1_dev == NULL) { device_printf(dev, "Unable to find NVIDIA Memory Controller 1.\n"); return (ENODEV); } /* Memory Controller 2 */ sc->mc2_dev = pci_find_bsf(pci_get_bus(dev), 0, 2); if (sc->mc2_dev == NULL) { device_printf(dev, "Unable to find NVIDIA Memory Controller 2.\n"); return (ENODEV); } /* AGP Host to PCI Bridge */ sc->bdev = pci_find_bsf(pci_get_bus(dev), 30, 0); if (sc->bdev == NULL) { device_printf(dev, "Unable to find NVIDIA AGP Host to PCI Bridge.\n"); return (ENODEV); } error = agp_generic_attach(dev); if (error) return (error); sc->initial_aperture = AGP_GET_APERTURE(dev); for (;;) { gatt = agp_alloc_gatt(dev); if (gatt) break; /* * Probably contigmalloc failure. Try reducing the * aperture so that the gatt size reduces. */ if (AGP_SET_APERTURE(dev, AGP_GET_APERTURE(dev) / 2)) goto fail; } sc->gatt = gatt; apbase = rman_get_start(sc->agp.as_aperture); aplimit = apbase + AGP_GET_APERTURE(dev) - 1; pci_write_config(sc->mc2_dev, AGP_NVIDIA_2_APBASE, apbase, 4); pci_write_config(sc->mc2_dev, AGP_NVIDIA_2_APLIMIT, aplimit, 4); pci_write_config(sc->bdev, AGP_NVIDIA_3_APBASE, apbase, 4); pci_write_config(sc->bdev, AGP_NVIDIA_3_APLIMIT, aplimit, 4); error = nvidia_init_iorr(apbase, AGP_GET_APERTURE(dev)); if (error) { device_printf(dev, "Failed to setup IORRs\n"); goto fail; } /* directory size is 64k */ size = AGP_GET_APERTURE(dev) / 1024 / 1024; sc->num_dirs = size / 64; sc->num_active_entries = (size == 32) ? 16384 : ((size * 1024) / 4); sc->pg_offset = 0; if (sc->num_dirs == 0) { sc->num_dirs = 1; sc->num_active_entries /= (64 / size); sc->pg_offset = (apbase & (64 * 1024 * 1024 - 1) & ~(AGP_GET_APERTURE(dev) - 1)) / PAGE_SIZE; } /* (G)ATT Base Address */ for (i = 0; i < 8; i++) { pci_write_config(sc->mc2_dev, AGP_NVIDIA_2_ATTBASE(i), (sc->gatt->ag_physical + (i % sc->num_dirs) * 64 * 1024) | 1, 4); } /* GTLB Control */ temp = pci_read_config(sc->mc2_dev, AGP_NVIDIA_2_GARTCTRL, 4); pci_write_config(sc->mc2_dev, AGP_NVIDIA_2_GARTCTRL, temp | 0x11, 4); /* GART Control */ temp = pci_read_config(sc->dev, AGP_NVIDIA_0_APSIZE, 4); pci_write_config(sc->dev, AGP_NVIDIA_0_APSIZE, temp | 0x100, 4); return (0); fail: agp_generic_detach(dev); return (ENOMEM); }
static int mpt_pci_probe(device_t dev) { const char *desc; int rval; if (pci_get_vendor(dev) != MPI_MANUFACTPAGE_VENDORID_LSILOGIC) return (ENXIO); rval = BUS_PROBE_DEFAULT; switch (pci_get_device(dev)) { case MPI_MANUFACTPAGE_DEVICEID_FC909_FB: desc = "LSILogic FC909 FC Adapter"; break; case MPI_MANUFACTPAGE_DEVICEID_FC909: desc = "LSILogic FC909A FC Adapter"; break; case MPI_MANUFACTPAGE_DEVICEID_FC919: desc = "LSILogic FC919 FC Adapter"; break; case MPI_MANUFACTPAGE_DEVICEID_FC919_LAN_FB: desc = "LSILogic FC919 LAN Adapter"; break; case MPI_MANUFACTPAGE_DEVICEID_FC929: desc = "Dual LSILogic FC929 FC Adapter"; break; case MPI_MANUFACTPAGE_DEVICEID_FC929_LAN_FB: desc = "Dual LSILogic FC929 LAN Adapter"; break; case MPI_MANUFACTPAGE_DEVICEID_FC919X: desc = "LSILogic FC919 FC PCI-X Adapter"; break; case MPI_MANUFACTPAGE_DEVICEID_FC919X_LAN_FB: desc = "LSILogic FC919 LAN PCI-X Adapter"; break; case MPI_MANUFACTPAGE_DEVICEID_FC929X: desc = "Dual LSILogic FC929X 2Gb/s FC PCI-X Adapter"; break; case MPI_MANUFACTPAGE_DEVICEID_FC929X_LAN_FB: desc = "Dual LSILogic FC929X LAN PCI-X Adapter"; break; case MPI_MANUFACTPAGE_DEVICEID_FC949E: desc = "Dual LSILogic FC7X04X 4Gb/s FC PCI-Express Adapter"; break; case MPI_MANUFACTPAGE_DEVICEID_FC949X: desc = "Dual LSILogic FC7X04X 4Gb/s FC PCI-X Adapter"; break; case MPI_MANUFACTPAGE_DEVID_53C1030: case MPI_MANUFACTPAGE_DEVID_53C1030ZC: desc = "LSILogic 1030 Ultra4 Adapter"; break; case MPI_MANUFACTPAGE_DEVID_SAS1068E_FB: /* * Allow mfi(4) to claim this device in case it's in MegaRAID * mode. */ rval = BUS_PROBE_LOW_PRIORITY; /* FALLTHROUGH */ case MPI_MANUFACTPAGE_DEVID_SAS1064: case MPI_MANUFACTPAGE_DEVID_SAS1064A: case MPI_MANUFACTPAGE_DEVID_SAS1064E: case MPI_MANUFACTPAGE_DEVID_SAS1066: case MPI_MANUFACTPAGE_DEVID_SAS1066E: case MPI_MANUFACTPAGE_DEVID_SAS1068: case MPI_MANUFACTPAGE_DEVID_SAS1068A_FB: case MPI_MANUFACTPAGE_DEVID_SAS1068E: case MPI_MANUFACTPAGE_DEVID_SAS1078: case MPI_MANUFACTPAGE_DEVID_SAS1078DE_FB: desc = "LSILogic SAS/SATA Adapter"; break; default: return (ENXIO); } device_set_desc(dev, desc); return (rval); }
static int cs5530_init_chip(void) { struct pci_dev *master_0 = NULL, *cs5530_0 = NULL, *dev = NULL; while ((dev = pci_get_device(PCI_VENDOR_ID_CYRIX, PCI_ANY_ID, dev)) != NULL) { switch (dev->device) { case PCI_DEVICE_ID_CYRIX_PCI_MASTER: master_0 = pci_dev_get(dev); break; case PCI_DEVICE_ID_CYRIX_5530_LEGACY: cs5530_0 = pci_dev_get(dev); break; } } if (!master_0) { printk(KERN_ERR DRV_NAME ": unable to locate PCI MASTER function\n"); goto fail_put; } if (!cs5530_0) { printk(KERN_ERR DRV_NAME ": unable to locate CS5530 LEGACY function\n"); goto fail_put; } pci_set_master(cs5530_0); pci_try_set_mwi(cs5530_0); /* * Set PCI CacheLineSize to 16-bytes: * --> Write 0x04 into 8-bit PCI CACHELINESIZE reg of function 0 of the cs5530 * * Note: This value is constant because the 5530 is only a Geode companion */ pci_write_config_byte(cs5530_0, PCI_CACHE_LINE_SIZE, 0x04); /* * Disable trapping of UDMA register accesses (Win98 hack): * --> Write 0x5006 into 16-bit reg at offset 0xd0 of function 0 of the cs5530 */ pci_write_config_word(cs5530_0, 0xd0, 0x5006); /* * Bit-1 at 0x40 enables MemoryWriteAndInvalidate on internal X-bus: * The other settings are what is necessary to get the register * into a sane state for IDE DMA operation. */ pci_write_config_byte(master_0, 0x40, 0x1e); /* * Set max PCI burst size (16-bytes seems to work best): * 16bytes: set bit-1 at 0x41 (reg value of 0x16) * all others: clear bit-1 at 0x41, and do: * 128bytes: OR 0x00 at 0x41 * 256bytes: OR 0x04 at 0x41 * 512bytes: OR 0x08 at 0x41 * 1024bytes: OR 0x0c at 0x41 */ pci_write_config_byte(master_0, 0x41, 0x14); /* * These settings are necessary to get the chip * into a sane state for IDE DMA operation. */ pci_write_config_byte(master_0, 0x42, 0x00); pci_write_config_byte(master_0, 0x43, 0xc1); pci_dev_put(master_0); pci_dev_put(cs5530_0); return 0; fail_put: if (master_0) pci_dev_put(master_0); if (cs5530_0) pci_dev_put(cs5530_0); return -ENODEV; }
static int tws_attach(device_t dev) { struct tws_softc *sc = device_get_softc(dev); u_int32_t bar; int error=0,i; /* no tracing yet */ /* Look up our softc and initialize its fields. */ sc->tws_dev = dev; sc->device_id = pci_get_device(dev); sc->subvendor_id = pci_get_subvendor(dev); sc->subdevice_id = pci_get_subdevice(dev); /* Intialize mutexes */ mtx_init( &sc->q_lock, "tws_q_lock", NULL, MTX_DEF); mtx_init( &sc->sim_lock, "tws_sim_lock", NULL, MTX_DEF); mtx_init( &sc->gen_lock, "tws_gen_lock", NULL, MTX_DEF); mtx_init( &sc->io_lock, "tws_io_lock", NULL, MTX_DEF | MTX_RECURSE); callout_init(&sc->stats_timer, CALLOUT_MPSAFE); if ( tws_init_trace_q(sc) == FAILURE ) printf("trace init failure\n"); /* send init event */ mtx_lock(&sc->gen_lock); tws_send_event(sc, TWS_INIT_START); mtx_unlock(&sc->gen_lock); #if _BYTE_ORDER == _BIG_ENDIAN TWS_TRACE(sc, "BIG endian", 0, 0); #endif /* sysctl context setup */ sysctl_ctx_init(&sc->tws_clist); sc->tws_oidp = SYSCTL_ADD_NODE(&sc->tws_clist, SYSCTL_STATIC_CHILDREN(_hw), OID_AUTO, device_get_nameunit(dev), CTLFLAG_RD, 0, ""); if ( sc->tws_oidp == NULL ) { tws_log(sc, SYSCTL_TREE_NODE_ADD); goto attach_fail_1; } SYSCTL_ADD_STRING(&sc->tws_clist, SYSCTL_CHILDREN(sc->tws_oidp), OID_AUTO, "driver_version", CTLFLAG_RD, TWS_DRIVER_VERSION_STRING, 0, "TWS driver version"); pci_enable_busmaster(dev); bar = pci_read_config(dev, TWS_PCI_BAR0, 4); TWS_TRACE_DEBUG(sc, "bar0 ", bar, 0); bar = pci_read_config(dev, TWS_PCI_BAR1, 4); bar = bar & ~TWS_BIT2; TWS_TRACE_DEBUG(sc, "bar1 ", bar, 0); /* MFA base address is BAR2 register used for * push mode. Firmware will evatualy move to * pull mode during witch this needs to change */ #ifndef TWS_PULL_MODE_ENABLE sc->mfa_base = (u_int64_t)pci_read_config(dev, TWS_PCI_BAR2, 4); sc->mfa_base = sc->mfa_base & ~TWS_BIT2; TWS_TRACE_DEBUG(sc, "bar2 ", sc->mfa_base, 0); #endif /* allocate MMIO register space */ sc->reg_res_id = TWS_PCI_BAR1; /* BAR1 offset */ if ((sc->reg_res = bus_alloc_resource(dev, SYS_RES_MEMORY, &(sc->reg_res_id), 0, ~0, 1, RF_ACTIVE)) == NULL) { tws_log(sc, ALLOC_MEMORY_RES); goto attach_fail_1; } sc->bus_tag = rman_get_bustag(sc->reg_res); sc->bus_handle = rman_get_bushandle(sc->reg_res); #ifndef TWS_PULL_MODE_ENABLE /* Allocate bus space for inbound mfa */ sc->mfa_res_id = TWS_PCI_BAR2; /* BAR2 offset */ if ((sc->mfa_res = bus_alloc_resource(dev, SYS_RES_MEMORY, &(sc->mfa_res_id), 0, ~0, 0x100000, RF_ACTIVE)) == NULL) { tws_log(sc, ALLOC_MEMORY_RES); goto attach_fail_2; } sc->bus_mfa_tag = rman_get_bustag(sc->mfa_res); sc->bus_mfa_handle = rman_get_bushandle(sc->mfa_res); #endif /* Allocate and register our interrupt. */ sc->intr_type = TWS_INTx; /* default */ if ( tws_enable_msi ) sc->intr_type = TWS_MSI; if ( tws_setup_irq(sc) == FAILURE ) { tws_log(sc, ALLOC_MEMORY_RES); goto attach_fail_3; } /* * Create a /dev entry for this device. The kernel will assign us * a major number automatically. We use the unit number of this * device as the minor number and name the character device * "tws<unit>". */ sc->tws_cdev = make_dev(&tws_cdevsw, device_get_unit(dev), UID_ROOT, GID_OPERATOR, S_IRUSR | S_IWUSR, "tws%u", device_get_unit(dev)); sc->tws_cdev->si_drv1 = sc; if ( tws_init(sc) == FAILURE ) { tws_log(sc, TWS_INIT_FAILURE); goto attach_fail_4; } if ( tws_init_ctlr(sc) == FAILURE ) { tws_log(sc, TWS_CTLR_INIT_FAILURE); goto attach_fail_4; } if ((error = tws_cam_attach(sc))) { tws_log(sc, TWS_CAM_ATTACH); goto attach_fail_4; } /* send init complete event */ mtx_lock(&sc->gen_lock); tws_send_event(sc, TWS_INIT_COMPLETE); mtx_unlock(&sc->gen_lock); TWS_TRACE_DEBUG(sc, "attached successfully", 0, sc->device_id); return(0); attach_fail_4: tws_teardown_intr(sc); destroy_dev(sc->tws_cdev); if (sc->dma_mem_phys) bus_dmamap_unload(sc->cmd_tag, sc->cmd_map); if (sc->dma_mem) bus_dmamem_free(sc->cmd_tag, sc->dma_mem, sc->cmd_map); if (sc->cmd_tag) bus_dma_tag_destroy(sc->cmd_tag); attach_fail_3: for(i=0;i<sc->irqs;i++) { if ( sc->irq_res[i] ){ if (bus_release_resource(sc->tws_dev, SYS_RES_IRQ, sc->irq_res_id[i], sc->irq_res[i])) TWS_TRACE(sc, "bus irq res", 0, 0); } } #ifndef TWS_PULL_MODE_ENABLE attach_fail_2: #endif if ( sc->mfa_res ){ if (bus_release_resource(sc->tws_dev, SYS_RES_MEMORY, sc->mfa_res_id, sc->mfa_res)) TWS_TRACE(sc, "bus release ", 0, sc->mfa_res_id); } if ( sc->reg_res ){ if (bus_release_resource(sc->tws_dev, SYS_RES_MEMORY, sc->reg_res_id, sc->reg_res)) TWS_TRACE(sc, "bus release2 ", 0, sc->reg_res_id); } attach_fail_1: mtx_destroy(&sc->q_lock); mtx_destroy(&sc->sim_lock); mtx_destroy(&sc->gen_lock); mtx_destroy(&sc->io_lock); sysctl_ctx_free(&sc->tws_clist); return (ENXIO); }
int hme_pci_attach(device_t dev) { struct hme_pci_softc *hsc; struct hme_softc *sc; bus_space_tag_t memt; bus_space_handle_t memh; int i, error = 0; #if !(defined(__powerpc__) || defined(__sparc64__)) device_t *children, ebus_dev; struct resource *ebus_rres; int j, slot; #endif pci_enable_busmaster(dev); /* * Some Sun HMEs do have their intpin register bogusly set to 0, * although it should be 1. Correct that. */ if (pci_get_intpin(dev) == 0) pci_set_intpin(dev, 1); hsc = device_get_softc(dev); sc = &hsc->hsc_hme; sc->sc_dev = dev; sc->sc_flags |= HME_PCI; mtx_init(&sc->sc_lock, device_get_nameunit(dev), MTX_NETWORK_LOCK, MTX_DEF); /* * Map five register banks: * * bank 0: HME SEB registers: +0x0000 * bank 1: HME ETX registers: +0x2000 * bank 2: HME ERX registers: +0x4000 * bank 3: HME MAC registers: +0x6000 * bank 4: HME MIF registers: +0x7000 * */ i = PCIR_BAR(0); hsc->hsc_sres = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &i, RF_ACTIVE); if (hsc->hsc_sres == NULL) { device_printf(dev, "could not map device registers\n"); error = ENXIO; goto fail_mtx; } i = 0; hsc->hsc_ires = bus_alloc_resource_any(dev, SYS_RES_IRQ, &i, RF_SHAREABLE | RF_ACTIVE); if (hsc->hsc_ires == NULL) { device_printf(dev, "could not allocate interrupt\n"); error = ENXIO; goto fail_sres; } memt = rman_get_bustag(hsc->hsc_sres); memh = rman_get_bushandle(hsc->hsc_sres); sc->sc_sebt = sc->sc_etxt = sc->sc_erxt = sc->sc_mact = sc->sc_mift = memt; bus_space_subregion(memt, memh, 0x0000, 0x1000, &sc->sc_sebh); bus_space_subregion(memt, memh, 0x2000, 0x1000, &sc->sc_etxh); bus_space_subregion(memt, memh, 0x4000, 0x1000, &sc->sc_erxh); bus_space_subregion(memt, memh, 0x6000, 0x1000, &sc->sc_mach); bus_space_subregion(memt, memh, 0x7000, 0x1000, &sc->sc_mifh); #if defined(__powerpc__) || defined(__sparc64__) OF_getetheraddr(dev, sc->sc_enaddr); #else /* * Dig out VPD (vital product data) and read NA (network address). * * The PCI HME is a PCIO chip, which is composed of two functions: * function 0: PCI-EBus2 bridge, and * function 1: HappyMeal Ethernet controller. * * The VPD of HME resides in the Boot PROM (PCI FCode) attached * to the EBus bridge and can't be accessed via the PCI capability * pointer. * ``Writing FCode 3.x Programs'' (newer ones, dated 1997 and later) * chapter 2 describes the data structure. * * We don't have a MI EBus driver since no EBus device exists * (besides the FCode PROM) on add-on HME boards. The ``no driver * attached'' message for function 0 therefore is what is expected. */ #define PCI_ROMHDR_SIZE 0x1c #define PCI_ROMHDR_SIG 0x00 #define PCI_ROMHDR_SIG_MAGIC 0xaa55 /* little endian */ #define PCI_ROMHDR_PTR_DATA 0x18 #define PCI_ROM_SIZE 0x18 #define PCI_ROM_SIG 0x00 #define PCI_ROM_SIG_MAGIC 0x52494350 /* "PCIR", endian */ /* reversed */ #define PCI_ROM_VENDOR 0x04 #define PCI_ROM_DEVICE 0x06 #define PCI_ROM_PTR_VPD 0x08 #define PCI_VPDRES_BYTE0 0x00 #define PCI_VPDRES_ISLARGE(x) ((x) & 0x80) #define PCI_VPDRES_LARGE_NAME(x) ((x) & 0x7f) #define PCI_VPDRES_TYPE_VPD 0x10 /* large */ #define PCI_VPDRES_LARGE_LEN_LSB 0x01 #define PCI_VPDRES_LARGE_LEN_MSB 0x02 #define PCI_VPDRES_LARGE_DATA 0x03 #define PCI_VPD_SIZE 0x03 #define PCI_VPD_KEY0 0x00 #define PCI_VPD_KEY1 0x01 #define PCI_VPD_LEN 0x02 #define PCI_VPD_DATA 0x03 #define HME_ROM_READ_N(n, offs) bus_space_read_ ## n (memt, memh, (offs)) #define HME_ROM_READ_1(offs) HME_ROM_READ_N(1, (offs)) #define HME_ROM_READ_2(offs) HME_ROM_READ_N(2, (offs)) #define HME_ROM_READ_4(offs) HME_ROM_READ_N(4, (offs)) /* Search accompanying EBus bridge. */ slot = pci_get_slot(dev); if (device_get_children(device_get_parent(dev), &children, &i) != 0) { device_printf(dev, "could not get children\n"); error = ENXIO; goto fail_sres; } ebus_dev = NULL; for (j = 0; j < i; j++) { if (pci_get_class(children[j]) == PCIC_BRIDGE && pci_get_vendor(children[j]) == PCI_VENDOR_SUN && pci_get_device(children[j]) == PCI_PRODUCT_SUN_EBUS && pci_get_slot(children[j]) == slot) { ebus_dev = children[j]; break; } } if (ebus_dev == NULL) { device_printf(dev, "could not find EBus bridge\n"); error = ENXIO; goto fail_children; } /* Map EBus bridge PROM registers. */ i = PCIR_BAR(0); if ((ebus_rres = bus_alloc_resource_any(ebus_dev, SYS_RES_MEMORY, &i, RF_ACTIVE)) == NULL) { device_printf(dev, "could not map PROM registers\n"); error = ENXIO; goto fail_children; } memt = rman_get_bustag(ebus_rres); memh = rman_get_bushandle(ebus_rres); /* Read PCI Expansion ROM header. */ if (HME_ROM_READ_2(PCI_ROMHDR_SIG) != PCI_ROMHDR_SIG_MAGIC || (i = HME_ROM_READ_2(PCI_ROMHDR_PTR_DATA)) < PCI_ROMHDR_SIZE) { device_printf(dev, "unexpected PCI Expansion ROM header\n"); error = ENXIO; goto fail_rres; } /* Read PCI Expansion ROM data. */ if (HME_ROM_READ_4(i + PCI_ROM_SIG) != PCI_ROM_SIG_MAGIC || HME_ROM_READ_2(i + PCI_ROM_VENDOR) != pci_get_vendor(dev) || HME_ROM_READ_2(i + PCI_ROM_DEVICE) != pci_get_device(dev) || (j = HME_ROM_READ_2(i + PCI_ROM_PTR_VPD)) < i + PCI_ROM_SIZE) { device_printf(dev, "unexpected PCI Expansion ROM data\n"); error = ENXIO; goto fail_rres; } /* * Read PCI VPD. * SUNW,hme cards have a single large resource VPD-R tag * containing one NA. SUNW,qfe cards have four large resource * VPD-R tags containing one NA each (all four HME chips share * the same PROM). * The VPD used on both cards is not in PCI 2.2 standard format * however. The length in the resource header is in big endian * and the end tag is non-standard (0x79) and followed by an * all-zero "checksum" byte. Sun calls this a "Fresh Choice * Ethernet" VPD... */ /* Look at the end tag to determine whether this is a VPD with 4 NAs. */ if (HME_ROM_READ_1(j + PCI_VPDRES_LARGE_DATA + PCI_VPD_SIZE + ETHER_ADDR_LEN) != 0x79 && HME_ROM_READ_1(j + 4 * (PCI_VPDRES_LARGE_DATA + PCI_VPD_SIZE + ETHER_ADDR_LEN)) == 0x79) /* Use the Nth NA for the Nth HME on this SUNW,qfe. */ j += slot * (PCI_VPDRES_LARGE_DATA + PCI_VPD_SIZE + ETHER_ADDR_LEN); if (PCI_VPDRES_ISLARGE(HME_ROM_READ_1(j + PCI_VPDRES_BYTE0)) == 0 || PCI_VPDRES_LARGE_NAME(HME_ROM_READ_1(j + PCI_VPDRES_BYTE0)) != PCI_VPDRES_TYPE_VPD || (HME_ROM_READ_1(j + PCI_VPDRES_LARGE_LEN_LSB) << 8 | HME_ROM_READ_1(j + PCI_VPDRES_LARGE_LEN_MSB)) != PCI_VPD_SIZE + ETHER_ADDR_LEN || HME_ROM_READ_1(j + PCI_VPDRES_LARGE_DATA + PCI_VPD_KEY0) != 0x4e /* N */ || HME_ROM_READ_1(j + PCI_VPDRES_LARGE_DATA + PCI_VPD_KEY1) != 0x41 /* A */ || HME_ROM_READ_1(j + PCI_VPDRES_LARGE_DATA + PCI_VPD_LEN) != ETHER_ADDR_LEN) { device_printf(dev, "unexpected PCI VPD\n"); error = ENXIO; goto fail_rres; } bus_space_read_region_1(memt, memh, j + PCI_VPDRES_LARGE_DATA + PCI_VPD_DATA, sc->sc_enaddr, ETHER_ADDR_LEN); fail_rres: bus_release_resource(ebus_dev, SYS_RES_MEMORY, rman_get_rid(ebus_rres), ebus_rres); fail_children: free(children, M_TEMP); if (error != 0) goto fail_sres; #endif sc->sc_burst = 64; /* XXX */ /* * call the main configure */ if ((error = hme_config(sc)) != 0) { device_printf(dev, "could not be configured\n"); goto fail_ires; } if ((error = bus_setup_intr(dev, hsc->hsc_ires, INTR_TYPE_NET | INTR_MPSAFE, NULL, hme_intr, sc, &hsc->hsc_ih)) != 0) { device_printf(dev, "couldn't establish interrupt\n"); hme_detach(sc); goto fail_ires; } return (0); fail_ires: bus_release_resource(dev, SYS_RES_IRQ, rman_get_rid(hsc->hsc_ires), hsc->hsc_ires); fail_sres: bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(hsc->hsc_sres), hsc->hsc_sres); fail_mtx: mtx_destroy(&sc->sc_lock); return (error); }
/* pasemi_dma_init - Initialize the PA Semi DMA library * * This function initializes the DMA library. It must be called before * any other function in the library. * * Returns 0 on success, errno on failure. */ int pasemi_dma_init(void) { static DEFINE_SPINLOCK(init_lock); struct pci_dev *iob_pdev; struct pci_dev *pdev; struct resource res; struct device_node *dn; int i, intf, err = 0; unsigned long timeout; u32 tmp; if (!machine_is(pasemi)) return -ENODEV; spin_lock(&init_lock); /* Make sure we haven't already initialized */ if (dma_pdev) goto out; iob_pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa001, NULL); if (!iob_pdev) { BUG(); printk(KERN_WARNING "Can't find I/O Bridge\n"); err = -ENODEV; goto out; } iob_regs = map_onedev(iob_pdev, 0); dma_pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa007, NULL); if (!dma_pdev) { BUG(); printk(KERN_WARNING "Can't find DMA controller\n"); err = -ENODEV; goto out; } dma_regs = map_onedev(dma_pdev, 0); base_hw_irq = virq_to_hw(dma_pdev->irq); pci_read_config_dword(dma_pdev, PAS_DMA_CAP_TXCH, &tmp); num_txch = (tmp & PAS_DMA_CAP_TXCH_TCHN_M) >> PAS_DMA_CAP_TXCH_TCHN_S; pci_read_config_dword(dma_pdev, PAS_DMA_CAP_RXCH, &tmp); num_rxch = (tmp & PAS_DMA_CAP_RXCH_RCHN_M) >> PAS_DMA_CAP_RXCH_RCHN_S; intf = 0; for (pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa006, NULL); pdev; pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa006, pdev)) mac_regs[intf++] = map_onedev(pdev, 0); pci_dev_put(pdev); for (pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa005, NULL); pdev; pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa005, pdev)) mac_regs[intf++] = map_onedev(pdev, 0); pci_dev_put(pdev); dn = pci_device_to_OF_node(iob_pdev); if (dn) err = of_address_to_resource(dn, 1, &res); if (!dn || err) { /* Fallback for old firmware */ res.start = 0xfd800000; res.end = res.start + 0x1000; } dma_status = __ioremap(res.start, res.end-res.start, 0); pci_dev_put(iob_pdev); for (i = 0; i < MAX_TXCH; i++) __set_bit(i, txch_free); for (i = 0; i < MAX_RXCH; i++) __set_bit(i, rxch_free); timeout = jiffies + HZ; pasemi_write_dma_reg(PAS_DMA_COM_RXCMD, 0); while (pasemi_read_dma_reg(PAS_DMA_COM_RXSTA) & 1) { if (time_after(jiffies, timeout)) { pr_warning("Warning: Could not disable RX section\n"); break; } } timeout = jiffies + HZ; pasemi_write_dma_reg(PAS_DMA_COM_TXCMD, 0); while (pasemi_read_dma_reg(PAS_DMA_COM_TXSTA) & 1) { if (time_after(jiffies, timeout)) { pr_warning("Warning: Could not disable TX section\n"); break; } } /* setup resource allocations for the different DMA sections */ tmp = pasemi_read_dma_reg(PAS_DMA_COM_CFG); pasemi_write_dma_reg(PAS_DMA_COM_CFG, tmp | 0x18000000); /* enable tx section */ pasemi_write_dma_reg(PAS_DMA_COM_TXCMD, PAS_DMA_COM_TXCMD_EN); /* enable rx section */ pasemi_write_dma_reg(PAS_DMA_COM_RXCMD, PAS_DMA_COM_RXCMD_EN); for (i = 0; i < MAX_FLAGS; i++) __set_bit(i, flags_free); for (i = 0; i < MAX_FUN; i++) __set_bit(i, fun_free); /* clear all status flags */ pasemi_write_dma_reg(PAS_DMA_TXF_CFLG0, 0xffffffff); pasemi_write_dma_reg(PAS_DMA_TXF_CFLG1, 0xffffffff); printk(KERN_INFO "PA Semi PWRficient DMA library initialized " "(%d tx, %d rx channels)\n", num_txch, num_rxch); out: spin_unlock(&init_lock); return err; }
static int jmicron_probe(struct sdhci_pci_chip *chip) { int ret; u16 mmcdev = 0; if (chip->pdev->revision == 0) { chip->quirks |= SDHCI_QUIRK_32BIT_DMA_ADDR | SDHCI_QUIRK_32BIT_DMA_SIZE | SDHCI_QUIRK_32BIT_ADMA_SIZE | SDHCI_QUIRK_RESET_AFTER_REQUEST | SDHCI_QUIRK_BROKEN_SMALL_PIO; } /* * JMicron chips can have two interfaces to the same hardware * in order to work around limitations in Microsoft's driver. * We need to make sure we only bind to one of them. * * This code assumes two things: * * 1. The PCI code adds subfunctions in order. * * 2. The MMC interface has a lower subfunction number * than the SD interface. */ if (chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB38X_SD) mmcdev = PCI_DEVICE_ID_JMICRON_JMB38X_MMC; else if (chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB388_SD) mmcdev = PCI_DEVICE_ID_JMICRON_JMB388_ESD; if (mmcdev) { struct pci_dev *sd_dev; sd_dev = NULL; while ((sd_dev = pci_get_device(PCI_VENDOR_ID_JMICRON, mmcdev, sd_dev)) != NULL) { if ((PCI_SLOT(chip->pdev->devfn) == PCI_SLOT(sd_dev->devfn)) && (chip->pdev->bus == sd_dev->bus)) break; } if (sd_dev) { pci_dev_put(sd_dev); dev_info(&chip->pdev->dev, "Refusing to bind to " "secondary interface.\n"); return -ENODEV; } } /* * JMicron chips need a bit of a nudge to enable the power * output pins. */ ret = jmicron_pmos(chip, 1); if (ret) { dev_err(&chip->pdev->dev, "Failure enabling card power\n"); return ret; } /* quirk for unsable RO-detection on JM388 chips */ if (chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB388_SD || chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB388_ESD) chip->quirks |= SDHCI_QUIRK_UNSTABLE_RO_DETECT; return 0; }
/* Attach the PHY to the MII bus */ static int brgphy_attach(device_t dev) { struct brgphy_softc *bsc; struct bge_softc *bge_sc = NULL; struct bce_softc *bce_sc = NULL; struct mii_softc *sc; struct mii_attach_args *ma; struct mii_data *mii; struct ifnet *ifp; int fast_ether; bsc = device_get_softc(dev); sc = &bsc->mii_sc; ma = device_get_ivars(dev); sc->mii_dev = device_get_parent(dev); mii = device_get_softc(sc->mii_dev); LIST_INSERT_HEAD(&mii->mii_phys, sc, mii_list); /* Initialize mii_softc structure */ sc->mii_inst = mii->mii_instance; sc->mii_phy = ma->mii_phyno; sc->mii_service = brgphy_service; sc->mii_pdata = mii; sc->mii_anegticks = MII_ANEGTICKS_GIGE; sc->mii_flags |= MIIF_NOISOLATE | MIIF_NOLOOP; mii->mii_instance++; /* Initialize brgphy_softc structure */ bsc->mii_oui = MII_OUI(ma->mii_id1, ma->mii_id2); bsc->mii_model = MII_MODEL(ma->mii_id2); bsc->mii_rev = MII_REV(ma->mii_id2); bsc->serdes_flags = 0; fast_ether = 0; if (bootverbose) device_printf(dev, "OUI 0x%06x, model 0x%04x, rev. %d\n", bsc->mii_oui, bsc->mii_model, bsc->mii_rev); /* Handle any special cases based on the PHY ID */ switch (bsc->mii_oui) { case MII_OUI_BROADCOM: case MII_OUI_BROADCOM2: break; case MII_OUI_xxBROADCOM: switch (bsc->mii_model) { case MII_MODEL_xxBROADCOM_BCM5706: /* * The 5464 PHY used in the 5706 supports both copper * and fiber interfaces over GMII. Need to check the * shadow registers to see which mode is actually * in effect, and therefore whether we have 5706C or * 5706S. */ PHY_WRITE(sc, BRGPHY_MII_SHADOW_1C, BRGPHY_SHADOW_1C_MODE_CTRL); if (PHY_READ(sc, BRGPHY_MII_SHADOW_1C) & BRGPHY_SHADOW_1C_ENA_1000X) { bsc->serdes_flags |= BRGPHY_5706S; sc->mii_flags |= MIIF_HAVEFIBER; } break; } break; case MII_OUI_xxBROADCOM_ALT1: switch (bsc->mii_model) { case MII_MODEL_xxBROADCOM_ALT1_BCM5708S: bsc->serdes_flags |= BRGPHY_5708S; sc->mii_flags |= MIIF_HAVEFIBER; break; } break; default: device_printf(dev, "Unrecognized OUI for PHY!\n"); } ifp = sc->mii_pdata->mii_ifp; /* Find the MAC driver associated with this PHY. */ if (strcmp(ifp->if_dname, "bge") == 0) { bge_sc = ifp->if_softc; } else if (strcmp(ifp->if_dname, "bce") == 0) { bce_sc = ifp->if_softc; } /* Todo: Need to add additional controllers such as 5906 & 5787F */ /* The 590x chips are 10/100 only. */ if (bge_sc && pci_get_vendor(bge_sc->bge_dev) == BCOM_VENDORID && (pci_get_device(bge_sc->bge_dev) == BCOM_DEVICEID_BCM5901 || pci_get_device(bge_sc->bge_dev) == BCOM_DEVICEID_BCM5901A2 || pci_get_device(bge_sc->bge_dev) == BCOM_DEVICEID_BCM5906 || pci_get_device(bge_sc->bge_dev) == BCOM_DEVICEID_BCM5906M)) { fast_ether = 1; sc->mii_anegticks = MII_ANEGTICKS; } brgphy_reset(sc); /* Read the PHY's capabilities. */ sc->mii_capabilities = PHY_READ(sc, MII_BMSR) & ma->mii_capmask; if (sc->mii_capabilities & BMSR_EXTSTAT) sc->mii_extcapabilities = PHY_READ(sc, MII_EXTSR); device_printf(dev, " "); #define ADD(m, c) ifmedia_add(&mii->mii_media, (m), (c), NULL) /* Create an instance of Ethernet media. */ ADD(IFM_MAKEWORD(IFM_ETHER, IFM_NONE, 0, sc->mii_inst), BMCR_ISO); /* Add the supported media types */ if ((sc->mii_flags & MIIF_HAVEFIBER) == 0) { ADD(IFM_MAKEWORD(IFM_ETHER, IFM_10_T, 0, sc->mii_inst), BRGPHY_S10); printf("10baseT, "); ADD(IFM_MAKEWORD(IFM_ETHER, IFM_10_T, IFM_FDX, sc->mii_inst), BRGPHY_S10 | BRGPHY_BMCR_FDX); printf("10baseT-FDX, "); ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, 0, sc->mii_inst), BRGPHY_S100); printf("100baseTX, "); ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, IFM_FDX, sc->mii_inst), BRGPHY_S100 | BRGPHY_BMCR_FDX); printf("100baseTX-FDX, "); if (fast_ether == 0) { ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_T, 0, sc->mii_inst), BRGPHY_S1000); printf("1000baseT, "); ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_T, IFM_FDX, sc->mii_inst), BRGPHY_S1000 | BRGPHY_BMCR_FDX); printf("1000baseT-FDX, "); } } else { ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_SX, IFM_FDX, sc->mii_inst), BRGPHY_S1000 | BRGPHY_BMCR_FDX); printf("1000baseSX-FDX, "); /* 2.5G support is a software enabled feature on the 5708S and 5709S. */ if (bce_sc && (bce_sc->bce_phy_flags & BCE_PHY_2_5G_CAPABLE_FLAG)) { ADD(IFM_MAKEWORD(IFM_ETHER, IFM_2500_SX, IFM_FDX, sc->mii_inst), 0); printf("2500baseSX-FDX, "); } } ADD(IFM_MAKEWORD(IFM_ETHER, IFM_AUTO, 0, sc->mii_inst), 0); printf("auto\n"); #undef ADD MIIBUS_MEDIAINIT(sc->mii_dev); return (0); }
static int gem_pci_attach(device_t dev) { struct gem_softc *sc; int i; #if defined(__powerpc__) || defined(__sparc64__) char buf[sizeof(GEM_SHARED_PINS)]; #else int j; #endif sc = device_get_softc(dev); sc->sc_variant = GEM_UNKNOWN; for (i = 0; gem_pci_devlist[i].gpd_desc != NULL; i++) { if (pci_get_devid(dev) == gem_pci_devlist[i].gpd_devid) { sc->sc_variant = gem_pci_devlist[i].gpd_variant; break; } } if (sc->sc_variant == GEM_UNKNOWN) { device_printf(dev, "unknown adaptor\n"); return (ENXIO); } pci_enable_busmaster(dev); /* * Some Sun GEMs/ERIs do have their intpin register bogusly set to 0, * although it should be 1. Correct that. */ if (pci_get_intpin(dev) == 0) pci_set_intpin(dev, 1); /* Set the PCI latency timer for Sun ERIs. */ if (sc->sc_variant == GEM_SUN_ERI) pci_write_config(dev, PCIR_LATTIMER, GEM_ERI_LATENCY_TIMER, 1); sc->sc_dev = dev; sc->sc_flags |= GEM_PCI; if (bus_alloc_resources(dev, gem_pci_res_spec, sc->sc_res)) { device_printf(dev, "failed to allocate resources\n"); bus_release_resources(dev, gem_pci_res_spec, sc->sc_res); return (ENXIO); } GEM_LOCK_INIT(sc, device_get_nameunit(dev)); /* * Derive GEM_RES_BANK2 from GEM_RES_BANK1. This seemed cleaner * with the old way of using copies of the bus tag and handle in * the softc along with bus_space_*()... */ sc->sc_res[GEM_RES_BANK2] = malloc(sizeof(*sc->sc_res[GEM_RES_BANK2]), M_DEVBUF, M_NOWAIT | M_ZERO); if (sc->sc_res[GEM_RES_BANK2] == NULL) { device_printf(dev, "failed to allocate bank2 resource\n"); goto fail; } rman_set_bustag(sc->sc_res[GEM_RES_BANK2], rman_get_bustag(sc->sc_res[GEM_RES_BANK1])); bus_space_subregion(rman_get_bustag(sc->sc_res[GEM_RES_BANK1]), rman_get_bushandle(sc->sc_res[GEM_RES_BANK1]), GEM_PCI_BANK2_OFFSET, GEM_PCI_BANK2_SIZE, &sc->sc_res[GEM_RES_BANK2]->r_bushandle); /* Determine whether we're running at 66MHz. */ if ((GEM_BANK2_READ_4(sc, GEM_PCI_BIF_CONFIG) & GEM_PCI_BIF_CNF_M66EN) != 0) sc->sc_flags |= GEM_PCI66; #if defined(__powerpc__) || defined(__sparc64__) OF_getetheraddr(dev, sc->sc_enaddr); if (OF_getprop(ofw_bus_get_node(dev), GEM_SHARED_PINS, buf, sizeof(buf)) > 0) { buf[sizeof(buf) - 1] = '\0'; if (strcmp(buf, GEM_SHARED_PINS_SERDES) == 0) sc->sc_flags |= GEM_SERDES; } #else /* * Dig out VPD (vital product data) and read NA (network address). * The VPD resides in the PCI Expansion ROM (PCI FCode) and can't * be accessed via the PCI capability pointer. * ``Writing FCode 3.x Programs'' (newer ones, dated 1997 and later) * chapter 2 describes the data structure. */ #define PCI_ROMHDR_SIZE 0x1c #define PCI_ROMHDR_SIG 0x00 #define PCI_ROMHDR_SIG_MAGIC 0xaa55 /* little endian */ #define PCI_ROMHDR_PTR_DATA 0x18 #define PCI_ROM_SIZE 0x18 #define PCI_ROM_SIG 0x00 #define PCI_ROM_SIG_MAGIC 0x52494350 /* "PCIR", endian */ /* reversed */ #define PCI_ROM_VENDOR 0x04 #define PCI_ROM_DEVICE 0x06 #define PCI_ROM_PTR_VPD 0x08 #define PCI_VPDRES_BYTE0 0x00 #define PCI_VPDRES_ISLARGE(x) ((x) & 0x80) #define PCI_VPDRES_LARGE_NAME(x) ((x) & 0x7f) #define PCI_VPDRES_LARGE_LEN_LSB 0x01 #define PCI_VPDRES_LARGE_LEN_MSB 0x02 #define PCI_VPDRES_LARGE_SIZE 0x03 #define PCI_VPDRES_TYPE_VPD 0x10 /* large */ #define PCI_VPD_KEY0 0x00 #define PCI_VPD_KEY1 0x01 #define PCI_VPD_LEN 0x02 #define PCI_VPD_SIZE 0x03 #define GEM_ROM_READ_1(sc, offs) \ GEM_BANK1_READ_1((sc), GEM_PCI_ROM_OFFSET + (offs)) #define GEM_ROM_READ_2(sc, offs) \ GEM_BANK1_READ_2((sc), GEM_PCI_ROM_OFFSET + (offs)) #define GEM_ROM_READ_4(sc, offs) \ GEM_BANK1_READ_4((sc), GEM_PCI_ROM_OFFSET + (offs)) /* Read PCI Expansion ROM header. */ if (GEM_ROM_READ_2(sc, PCI_ROMHDR_SIG) != PCI_ROMHDR_SIG_MAGIC || (i = GEM_ROM_READ_2(sc, PCI_ROMHDR_PTR_DATA)) < PCI_ROMHDR_SIZE) { device_printf(dev, "unexpected PCI Expansion ROM header\n"); goto fail; } /* Read PCI Expansion ROM data. */ if (GEM_ROM_READ_4(sc, i + PCI_ROM_SIG) != PCI_ROM_SIG_MAGIC || GEM_ROM_READ_2(sc, i + PCI_ROM_VENDOR) != pci_get_vendor(dev) || GEM_ROM_READ_2(sc, i + PCI_ROM_DEVICE) != pci_get_device(dev) || (j = GEM_ROM_READ_2(sc, i + PCI_ROM_PTR_VPD)) < i + PCI_ROM_SIZE) { device_printf(dev, "unexpected PCI Expansion ROM data\n"); goto fail; } /* * Read PCI VPD. * SUNW,pci-gem cards have a single large resource VPD-R tag * containing one NA. The VPD used is not in PCI 2.2 standard * format however. The length in the resource header is in big * endian and the end tag is non-standard (0x79) and followed * by an all-zero "checksum" byte. Sun calls this a "Fresh * Choice Ethernet" VPD... */ if (PCI_VPDRES_ISLARGE(GEM_ROM_READ_1(sc, j + PCI_VPDRES_BYTE0)) == 0 || PCI_VPDRES_LARGE_NAME(GEM_ROM_READ_1(sc, j + PCI_VPDRES_BYTE0)) != PCI_VPDRES_TYPE_VPD || ((GEM_ROM_READ_1(sc, j + PCI_VPDRES_LARGE_LEN_LSB) << 8) | GEM_ROM_READ_1(sc, j + PCI_VPDRES_LARGE_LEN_MSB)) != PCI_VPD_SIZE + ETHER_ADDR_LEN || GEM_ROM_READ_1(sc, j + PCI_VPDRES_LARGE_SIZE + PCI_VPD_KEY0) != 0x4e /* N */ || GEM_ROM_READ_1(sc, j + PCI_VPDRES_LARGE_SIZE + PCI_VPD_KEY1) != 0x41 /* A */ || GEM_ROM_READ_1(sc, j + PCI_VPDRES_LARGE_SIZE + PCI_VPD_LEN) != ETHER_ADDR_LEN || GEM_ROM_READ_1(sc, j + PCI_VPDRES_LARGE_SIZE + PCI_VPD_SIZE + ETHER_ADDR_LEN) != 0x79) { device_printf(dev, "unexpected PCI VPD\n"); goto fail; } bus_read_region_1(sc->sc_res[GEM_RES_BANK1], GEM_PCI_ROM_OFFSET + j + PCI_VPDRES_LARGE_SIZE + PCI_VPD_SIZE, sc->sc_enaddr, ETHER_ADDR_LEN); #endif /* * The Xserve G5 has a fake GMAC with an all-zero MAC address. * Check for this, and don't attach in this case. */ for (i = 0; i < ETHER_ADDR_LEN && sc->sc_enaddr[i] == 0; i++) {} if (i == ETHER_ADDR_LEN) { device_printf(dev, "invalid MAC address\n"); goto fail; } if (gem_attach(sc) != 0) { device_printf(dev, "could not be attached\n"); goto fail; } if (bus_setup_intr(dev, sc->sc_res[GEM_RES_INTR], INTR_TYPE_NET | INTR_MPSAFE, NULL, gem_intr, sc, &sc->sc_ih) != 0) { device_printf(dev, "failed to set up interrupt\n"); gem_detach(sc); goto fail; } return (0); fail: if (sc->sc_res[GEM_RES_BANK2] != NULL) free(sc->sc_res[GEM_RES_BANK2], M_DEVBUF); GEM_LOCK_DESTROY(sc); bus_release_resources(dev, gem_pci_res_spec, sc->sc_res); return (ENXIO); }
/* called during probe() after chip reset completes */ static int ehci_pci_setup(struct usb_hcd *hcd) { struct ehci_hcd *ehci = hcd_to_ehci(hcd); struct pci_dev *pdev = to_pci_dev(hcd->self.controller); struct pci_dev *p_smbus; u8 rev; u32 temp; int retval; ehci->caps = hcd->regs; /* * ehci_init() causes memory for DMA transfers to be * allocated. Thus, any vendor-specific workarounds based on * limiting the type of memory used for DMA transfers must * happen before ehci_setup() is called. * * Most other workarounds can be done either before or after * init and reset; they are located here too. */ switch (pdev->vendor) { case PCI_VENDOR_ID_TOSHIBA_2: /* celleb's companion chip */ if (pdev->device == 0x01b5) { #ifdef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO ehci->big_endian_mmio = 1; #else ehci_warn(ehci, "unsupported big endian Toshiba quirk\n"); #endif } break; case PCI_VENDOR_ID_NVIDIA: /* NVidia reports that certain chips don't handle * QH, ITD, or SITD addresses above 2GB. (But TD, * data buffer, and periodic schedule are normal.) */ switch (pdev->device) { case 0x003c: /* MCP04 */ case 0x005b: /* CK804 */ case 0x00d8: /* CK8 */ case 0x00e8: /* CK8S */ if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(31)) < 0) ehci_warn(ehci, "can't enable NVidia " "workaround for >2GB RAM\n"); break; /* Some NForce2 chips have problems with selective suspend; * fixed in newer silicon. */ case 0x0068: if (pdev->revision < 0xa4) ehci->no_selective_suspend = 1; break; } break; case PCI_VENDOR_ID_INTEL: ehci->fs_i_thresh = 1; if (pdev->device == PCI_DEVICE_ID_INTEL_CE4100_USB) hcd->has_tt = 1; break; case PCI_VENDOR_ID_TDI: if (pdev->device == PCI_DEVICE_ID_TDI_EHCI) hcd->has_tt = 1; break; case PCI_VENDOR_ID_AMD: /* AMD PLL quirk */ if (usb_amd_find_chipset_info()) ehci->amd_pll_fix = 1; /* AMD8111 EHCI doesn't work, according to AMD errata */ if (pdev->device == 0x7463) { ehci_info(ehci, "ignoring AMD8111 (errata)\n"); retval = -EIO; goto done; } /* * EHCI controller on AMD SB700/SB800/Hudson-2/3 platforms may * read/write memory space which does not belong to it when * there is NULL pointer with T-bit set to 1 in the frame list * table. To avoid the issue, the frame list link pointer * should always contain a valid pointer to a inactive qh. */ if (pdev->device == 0x7808) { ehci->use_dummy_qh = 1; ehci_info(ehci, "applying AMD SB700/SB800/Hudson-2/3 EHCI dummy qh workaround\n"); } break; case PCI_VENDOR_ID_VIA: if (pdev->device == 0x3104 && (pdev->revision & 0xf0) == 0x60) { u8 tmp; /* The VT6212 defaults to a 1 usec EHCI sleep time which * hogs the PCI bus *badly*. Setting bit 5 of 0x4B makes * that sleep time use the conventional 10 usec. */ pci_read_config_byte(pdev, 0x4b, &tmp); if (tmp & 0x20) break; pci_write_config_byte(pdev, 0x4b, tmp | 0x20); } break; case PCI_VENDOR_ID_ATI: /* AMD PLL quirk */ if (usb_amd_find_chipset_info()) ehci->amd_pll_fix = 1; /* * EHCI controller on AMD SB700/SB800/Hudson-2/3 platforms may * read/write memory space which does not belong to it when * there is NULL pointer with T-bit set to 1 in the frame list * table. To avoid the issue, the frame list link pointer * should always contain a valid pointer to a inactive qh. */ if (pdev->device == 0x4396) { ehci->use_dummy_qh = 1; ehci_info(ehci, "applying AMD SB700/SB800/Hudson-2/3 EHCI dummy qh workaround\n"); } /* SB600 and old version of SB700 have a bug in EHCI controller, * which causes usb devices lose response in some cases. */ if ((pdev->device == 0x4386) || (pdev->device == 0x4396)) { p_smbus = pci_get_device(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_SBX00_SMBUS, NULL); if (!p_smbus) break; rev = p_smbus->revision; if ((pdev->device == 0x4386) || (rev == 0x3a) || (rev == 0x3b)) { u8 tmp; ehci_info(ehci, "applying AMD SB600/SB700 USB " "freeze workaround\n"); pci_read_config_byte(pdev, 0x53, &tmp); pci_write_config_byte(pdev, 0x53, tmp | (1<<3)); } pci_dev_put(p_smbus); } break; case PCI_VENDOR_ID_NETMOS: /* MosChip frame-index-register bug */ ehci_info(ehci, "applying MosChip frame-index workaround\n"); ehci->frame_index_bug = 1; break; } retval = ehci_setup(hcd); if (retval) return retval; /* These workarounds need to be applied after ehci_setup() */ switch (pdev->vendor) { case PCI_VENDOR_ID_NEC: ehci->need_io_watchdog = 0; break; case PCI_VENDOR_ID_INTEL: ehci->need_io_watchdog = 0; if (pdev->device == 0x0806 || pdev->device == 0x0811 || pdev->device == 0x0829) { ehci_info(ehci, "disable lpm for langwell/penwell\n"); ehci->has_lpm = 0; } break; case PCI_VENDOR_ID_NVIDIA: switch (pdev->device) { /* MCP89 chips on the MacBookAir3,1 give EPROTO when * fetching device descriptors unless LPM is disabled. * There are also intermittent problems enumerating * devices with PPCD enabled. */ case 0x0d9d: ehci_info(ehci, "disable lpm/ppcd for nvidia mcp89"); ehci->has_lpm = 0; ehci->has_ppcd = 0; ehci->command &= ~CMD_PPCEE; break; } break; } /* optional debug port, normally in the first BAR */ temp = pci_find_capability(pdev, 0x0a); if (temp) { pci_read_config_dword(pdev, temp, &temp); temp >>= 16; if ((temp & (3 << 13)) == (1 << 13)) { temp &= 0x1fff; ehci->debug = hcd->regs + temp; temp = ehci_readl(ehci, &ehci->debug->control); ehci_info(ehci, "debug port %d%s\n", HCS_DEBUG_PORT(ehci->hcs_params), (temp & DBGP_ENABLED) ? " IN USE" : ""); if (!(temp & DBGP_ENABLED)) ehci->debug = NULL; } } /* at least the Genesys GL880S needs fixup here */ temp = HCS_N_CC(ehci->hcs_params) * HCS_N_PCC(ehci->hcs_params); temp &= 0x0f; if (temp && HCS_N_PORTS(ehci->hcs_params) > temp) { ehci_dbg(ehci, "bogus port configuration: " "cc=%d x pcc=%d < ports=%d\n", HCS_N_CC(ehci->hcs_params), HCS_N_PCC(ehci->hcs_params), HCS_N_PORTS(ehci->hcs_params)); switch (pdev->vendor) { case 0x17a0: /* GENESYS */ /* GL880S: should be PORTS=2 */ temp |= (ehci->hcs_params & ~0xf); ehci->hcs_params = temp; break; case PCI_VENDOR_ID_NVIDIA: /* NF4: should be PCC=10 */ break; } } /* Serial Bus Release Number is at PCI 0x60 offset */ if (pdev->vendor == PCI_VENDOR_ID_STMICRO && pdev->device == PCI_DEVICE_ID_STMICRO_USB_HOST) ; /* ConneXT has no sbrn register */ else pci_read_config_byte(pdev, 0x60, &ehci->sbrn); /* Keep this around for a while just in case some EHCI * implementation uses legacy PCI PM support. This test * can be removed on 17 Dec 2009 if the dev_warn() hasn't * been triggered by then. */ if (!device_can_wakeup(&pdev->dev)) { u16 port_wake; pci_read_config_word(pdev, 0x62, &port_wake); if (port_wake & 0x0001) { dev_warn(&pdev->dev, "Enabling legacy PCI PM\n"); device_set_wakeup_capable(&pdev->dev, 1); } } #ifdef CONFIG_USB_SUSPEND /* REVISIT: the controller works fine for wakeup iff the root hub * itself is "globally" suspended, but usbcore currently doesn't * understand such things. * * System suspend currently expects to be able to suspend the entire * device tree, device-at-a-time. If we failed selective suspend * reports, system suspend would fail; so the root hub code must claim * success. That's lying to usbcore, and it matters for runtime * PM scenarios with selective suspend and remote wakeup... */ if (ehci->no_selective_suspend && device_can_wakeup(&pdev->dev)) ehci_warn(ehci, "selective suspend/wakeup unavailable\n"); #endif ehci_port_power(ehci, 1); retval = ehci_pci_reinit(ehci, pdev); done: return retval; }
/* * Function name: twa_attach * Description: Allocates pci resources; updates sc; adds a node to the * sysctl tree to expose the driver version; makes calls * (to the Common Layer) to initialize ctlr, and to * attach to CAM. * * Input: dev -- bus device corresponding to the ctlr * Output: None * Return value: 0 -- success * non-zero-- failure */ static TW_INT32 twa_attach(device_t dev) { struct twa_softc *sc = device_get_softc(dev); TW_INT32 bar_num; TW_INT32 bar0_offset; TW_INT32 bar_size; TW_INT32 error; tw_osli_dbg_dprintf(3, sc, "entered"); sc->ctlr_handle.osl_ctlr_ctxt = sc; /* Initialize the softc structure. */ sc->bus_dev = dev; sc->device_id = pci_get_device(dev); /* Initialize the mutexes right here. */ sc->io_lock = &(sc->io_lock_handle); mtx_init(sc->io_lock, "tw_osl_io_lock", NULL, MTX_SPIN); sc->q_lock = &(sc->q_lock_handle); mtx_init(sc->q_lock, "tw_osl_q_lock", NULL, MTX_SPIN); sc->sim_lock = &(sc->sim_lock_handle); mtx_init(sc->sim_lock, "tw_osl_sim_lock", NULL, MTX_DEF | MTX_RECURSE); sysctl_ctx_init(&sc->sysctl_ctxt); sc->sysctl_tree = SYSCTL_ADD_NODE(&sc->sysctl_ctxt, SYSCTL_STATIC_CHILDREN(_hw), OID_AUTO, device_get_nameunit(dev), CTLFLAG_RD, 0, ""); if (sc->sysctl_tree == NULL) { tw_osli_printf(sc, "error = %d", TW_CL_SEVERITY_ERROR_STRING, TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER, 0x2000, "Cannot add sysctl tree node", ENXIO); return(ENXIO); } SYSCTL_ADD_STRING(&sc->sysctl_ctxt, SYSCTL_CHILDREN(sc->sysctl_tree), OID_AUTO, "driver_version", CTLFLAG_RD, TW_OSL_DRIVER_VERSION_STRING, 0, "TWA driver version"); /* Force the busmaster enable bit on, in case the BIOS forgot. */ pci_enable_busmaster(dev); /* Allocate the PCI register window. */ if ((error = tw_cl_get_pci_bar_info(sc->device_id, TW_CL_BAR_TYPE_MEM, &bar_num, &bar0_offset, &bar_size))) { tw_osli_printf(sc, "error = %d", TW_CL_SEVERITY_ERROR_STRING, TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER, 0x201F, "Can't get PCI BAR info", error); tw_osli_free_resources(sc); return(error); } sc->reg_res_id = PCIR_BARS + bar0_offset; if ((sc->reg_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &(sc->reg_res_id), RF_ACTIVE)) == NULL) { tw_osli_printf(sc, "error = %d", TW_CL_SEVERITY_ERROR_STRING, TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER, 0x2002, "Can't allocate register window", ENXIO); tw_osli_free_resources(sc); return(ENXIO); } sc->bus_tag = rman_get_bustag(sc->reg_res); sc->bus_handle = rman_get_bushandle(sc->reg_res); /* Allocate and register our interrupt. */ sc->irq_res_id = 0; if ((sc->irq_res = bus_alloc_resource_any(sc->bus_dev, SYS_RES_IRQ, &(sc->irq_res_id), RF_SHAREABLE | RF_ACTIVE)) == NULL) { tw_osli_printf(sc, "error = %d", TW_CL_SEVERITY_ERROR_STRING, TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER, 0x2003, "Can't allocate interrupt", ENXIO); tw_osli_free_resources(sc); return(ENXIO); } if ((error = twa_setup_intr(sc))) { tw_osli_printf(sc, "error = %d", TW_CL_SEVERITY_ERROR_STRING, TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER, 0x2004, "Can't set up interrupt", error); tw_osli_free_resources(sc); return(error); } if ((error = tw_osli_alloc_mem(sc))) { tw_osli_printf(sc, "error = %d", TW_CL_SEVERITY_ERROR_STRING, TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER, 0x2005, "Memory allocation failure", error); tw_osli_free_resources(sc); return(error); } /* Initialize the Common Layer for this controller. */ if ((error = tw_cl_init_ctlr(&sc->ctlr_handle, sc->flags, sc->device_id, TW_OSLI_MAX_NUM_REQUESTS, TW_OSLI_MAX_NUM_AENS, sc->non_dma_mem, sc->dma_mem, sc->dma_mem_phys ))) { tw_osli_printf(sc, "error = %d", TW_CL_SEVERITY_ERROR_STRING, TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER, 0x2006, "Failed to initialize Common Layer/controller", error); tw_osli_free_resources(sc); return(error); } /* Create the control device. */ sc->ctrl_dev = make_dev(&twa_cdevsw, device_get_unit(sc->bus_dev), UID_ROOT, GID_OPERATOR, S_IRUSR | S_IWUSR, "twa%d", device_get_unit(sc->bus_dev)); sc->ctrl_dev->si_drv1 = sc; if ((error = tw_osli_cam_attach(sc))) { tw_osli_free_resources(sc); tw_osli_printf(sc, "error = %d", TW_CL_SEVERITY_ERROR_STRING, TW_CL_MESSAGE_SOURCE_FREEBSD_DRIVER, 0x2007, "Failed to initialize CAM", error); return(error); } sc->watchdog_index = 0; callout_init(&(sc->watchdog_callout[0]), 1); callout_init(&(sc->watchdog_callout[1]), 1); callout_reset(&(sc->watchdog_callout[0]), 5*hz, twa_watchdog, &sc->ctlr_handle); return(0); }
static int __init bbswitch_init(void) { struct proc_dir_entry *acpi_entry; struct pci_dev *pdev = NULL; acpi_handle igd_handle = NULL; pr_info("version %s\n", BBSWITCH_VERSION); while ((pdev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) { struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER, NULL }; acpi_handle handle; int pci_class = pdev->class >> 8; if (pci_class != PCI_CLASS_DISPLAY_VGA && pci_class != PCI_CLASS_DISPLAY_3D) continue; handle = DEVICE_ACPI_HANDLE(&pdev->dev); if (!handle) { pr_warn("cannot find ACPI handle for VGA device %s\n", dev_name(&pdev->dev)); continue; } acpi_get_name(handle, ACPI_FULL_PATHNAME, &buf); if (pdev->vendor == PCI_VENDOR_ID_INTEL) { igd_handle = handle; pr_info("Found integrated VGA device %s: %s\n", dev_name(&pdev->dev), (char *)buf.pointer); } else { dis_dev = pdev; dis_handle = handle; pr_info("Found discrete VGA device %s: %s\n", dev_name(&pdev->dev), (char *)buf.pointer); } kfree(buf.pointer); } if (dis_dev == NULL) { pr_err("No discrete VGA device found\n"); return -ENODEV; } if (has_dsm_func(acpi_optimus_dsm_muid, 0x100, 0x1A)) { dsm_type = DSM_TYPE_OPTIMUS; pr_info("detected an Optimus _DSM function\n"); } else if (has_dsm_func(acpi_nvidia_dsm_muid, 0x102, 0x3)) { dsm_type = DSM_TYPE_NVIDIA; pr_info("detected a nVidia _DSM function\n"); } else { /* At least two Acer machines are known to use the intel ACPI handle * with the legacy nvidia DSM */ dis_handle = igd_handle; if (has_dsm_func(acpi_nvidia_dsm_muid, 0x102, 0x3)) { dsm_type = DSM_TYPE_NVIDIA; pr_info("detected a nVidia _DSM function on the" " integrated video card\n"); } else { pr_err("No suitable _DSM call found.\n"); return -ENODEV; } } acpi_entry = proc_create("bbswitch", 0664, acpi_root_dir, &bbswitch_fops); if (acpi_entry == NULL) { pr_err("Couldn't create proc entry\n"); return -ENOMEM; } dis_dev_get(); if (load_state == CARD_ON) bbswitch_on(); else if (load_state == CARD_OFF) bbswitch_off(); pr_info("Succesfully loaded. Discrete card %s is %s\n", dev_name(&dis_dev->dev), is_card_disabled() ? "off" : "on"); dis_dev_put(); nb.notifier_call = &bbswitch_pm_handler; register_pm_notifier(&nb); return 0; }
static int ath_pci_attach(device_t dev) { struct ath_pci_softc *psc = device_get_softc(dev); struct ath_softc *sc = &psc->sc_sc; int error = ENXIO; int rid; sc->sc_dev = dev; /* * Enable bus mastering. */ pci_enable_busmaster(dev); /* * Disable retry timeout to keep PCI Tx retries from * interfering with C3 CPU state. */ pci_write_config(dev, PCIR_RETRY_TIMEOUT, 0, 1); /* * Setup memory-mapping of PCI registers. */ rid = BS_BAR; psc->sc_sr = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); if (psc->sc_sr == NULL) { device_printf(dev, "cannot map register space\n"); goto bad; } /* XXX uintptr_t is a bandaid for ia64; to be fixed */ sc->sc_st = (HAL_BUS_TAG)(uintptr_t) rman_get_bustag(psc->sc_sr); sc->sc_sh = (HAL_BUS_HANDLE) rman_get_bushandle(psc->sc_sr); /* * Mark device invalid so any interrupts (shared or otherwise) * that arrive before the HAL is setup are discarded. */ sc->sc_invalid = 1; /* * Arrange interrupt line. */ rid = 0; psc->sc_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_SHAREABLE|RF_ACTIVE); if (psc->sc_irq == NULL) { device_printf(dev, "could not map interrupt\n"); goto bad1; } if (bus_setup_intr(dev, psc->sc_irq, INTR_TYPE_NET | INTR_MPSAFE, NULL, ath_intr, sc, &psc->sc_ih)) { device_printf(dev, "could not establish interrupt\n"); goto bad2; } /* * Setup DMA descriptor area. */ if (bus_dma_tag_create(bus_get_dma_tag(dev), /* parent */ 1, 0, /* alignment, bounds */ BUS_SPACE_MAXADDR_32BIT, /* lowaddr */ BUS_SPACE_MAXADDR, /* highaddr */ NULL, NULL, /* filter, filterarg */ 0x3ffff, /* maxsize XXX */ ATH_MAX_SCATTER, /* nsegments */ 0x3ffff, /* maxsegsize XXX */ BUS_DMA_ALLOCNOW, /* flags */ NULL, /* lockfunc */ NULL, /* lockarg */ &sc->sc_dmat)) { device_printf(dev, "cannot allocate DMA tag\n"); goto bad3; } ATH_LOCK_INIT(sc); error = ath_attach(pci_get_device(dev), sc); if (error == 0) /* success */ return 0; ATH_LOCK_DESTROY(sc); bus_dma_tag_destroy(sc->sc_dmat); bad3: bus_teardown_intr(dev, psc->sc_irq, psc->sc_ih); bad2: bus_release_resource(dev, SYS_RES_IRQ, 0, psc->sc_irq); bad1: bus_release_resource(dev, SYS_RES_MEMORY, BS_BAR, psc->sc_sr); bad: return (error); }
static int __init init_l440gx(void) { struct pci_dev *dev, *pm_dev; struct resource *pm_iobase; __u16 word; dev = pci_get_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_0, NULL); pm_dev = pci_get_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3, NULL); pci_dev_put(dev); if (!dev || !pm_dev) { printk(KERN_NOTICE "L440GX flash mapping: failed to find PIIX4 ISA bridge, cannot continue\n"); pci_dev_put(pm_dev); return -ENODEV; } l440gx_map.virt = ioremap_nocache(WINDOW_ADDR, WINDOW_SIZE); if (!l440gx_map.virt) { printk(KERN_WARNING "Failed to ioremap L440GX flash region\n"); pci_dev_put(pm_dev); return -ENOMEM; } simple_map_init(&l440gx_map); printk(KERN_NOTICE "window_addr = 0x%08lx\n", (unsigned long)l440gx_map.virt); /* Setup the pm iobase resource * This code should move into some kind of generic bridge * driver but for the moment I'm content with getting the * allocation correct. */ pm_iobase = &pm_dev->resource[PIIXE_IOBASE_RESOURCE]; if (!(pm_iobase->flags & IORESOURCE_IO)) { pm_iobase->name = "pm iobase"; pm_iobase->start = 0; pm_iobase->end = 63; pm_iobase->flags = IORESOURCE_IO; /* Put the current value in the resource */ pci_read_config_dword(pm_dev, 0x40, &iobase); iobase &= ~1; pm_iobase->start += iobase & ~1; pm_iobase->end += iobase & ~1; pci_dev_put(pm_dev); /* Allocate the resource region */ if (pci_assign_resource(pm_dev, PIIXE_IOBASE_RESOURCE) != 0) { pci_dev_put(dev); pci_dev_put(pm_dev); printk(KERN_WARNING "Could not allocate pm iobase resource\n"); iounmap(l440gx_map.virt); return -ENXIO; } } /* Set the iobase */ iobase = pm_iobase->start; pci_write_config_dword(pm_dev, 0x40, iobase | 1); /* Set XBCS# */ pci_read_config_word(dev, 0x4e, &word); word |= 0x4; pci_write_config_word(dev, 0x4e, word); /* Supply write voltage to the chip */ l440gx_set_vpp(&l440gx_map, 1); /* Enable the gate on the WE line */ outb(inb(TRIBUF_PORT) & ~1, TRIBUF_PORT); printk(KERN_NOTICE "Enabled WE line to L440GX BIOS flash chip.\n"); mymtd = do_map_probe("jedec_probe", &l440gx_map); if (!mymtd) { printk(KERN_NOTICE "JEDEC probe on BIOS chip failed. Using ROM\n"); mymtd = do_map_probe("map_rom", &l440gx_map); } if (mymtd) { mymtd->owner = THIS_MODULE; mtd_device_register(mymtd, NULL, 0); return 0; } iounmap(l440gx_map.virt); return -ENXIO; }
int mthca_reset(struct mthca_dev *mdev) { int i; int err = 0; u32 *hca_header = NULL; u32 *bridge_header = NULL; struct pci_dev *bridge = NULL; int bridge_pcix_cap = 0; int hca_pcie_cap = 0; int hca_pcix_cap = 0; u16 devctl; u16 linkctl; #define MTHCA_RESET_OFFSET 0xf0010 #define MTHCA_RESET_VALUE swab32(1) /* * Reset the chip. This is somewhat ugly because we have to * save off the PCI header before reset and then restore it * after the chip reboots. We skip config space offsets 22 * and 23 since those have a special meaning. * * To make matters worse, for Tavor (PCI-X HCA) we have to * find the associated bridge device and save off its PCI * header as well. */ if (!(mdev->mthca_flags & MTHCA_FLAG_PCIE)) { /* Look for the bridge -- its device ID will be 2 more than HCA's device ID. */ while ((bridge = pci_get_device(mdev->pdev->vendor, mdev->pdev->device + 2, bridge)) != NULL) { if (bridge->hdr_type == PCI_HEADER_TYPE_BRIDGE && bridge->subordinate == mdev->pdev->bus) { mthca_dbg(mdev, "Found bridge: %s\n", pci_name(bridge)); break; } } if (!bridge) { /* * Didn't find a bridge for a Tavor device -- * assume we're in no-bridge mode and hope for * the best. */ mthca_warn(mdev, "No bridge found for %s\n", pci_name(mdev->pdev)); } } /* For Arbel do we need to save off the full 4K PCI Express header?? */ hca_header = kmalloc(256, GFP_KERNEL); if (!hca_header) { err = -ENOMEM; goto put_dev; } for (i = 0; i < 64; ++i) { if (i == 22 || i == 23) continue; if (pci_read_config_dword(mdev->pdev, i * 4, hca_header + i)) { err = -ENODEV; mthca_err(mdev, "Couldn't save HCA " "PCI header, aborting.\n"); goto free_hca; } } hca_pcix_cap = pci_find_capability(mdev->pdev, PCI_CAP_ID_PCIX); hca_pcie_cap = pci_pcie_cap(mdev->pdev); if (bridge) { bridge_header = kmalloc(256, GFP_KERNEL); if (!bridge_header) { err = -ENOMEM; goto free_hca; } for (i = 0; i < 64; ++i) { if (i == 22 || i == 23) continue; if (pci_read_config_dword(bridge, i * 4, bridge_header + i)) { err = -ENODEV; mthca_err(mdev, "Couldn't save HCA bridge " "PCI header, aborting.\n"); goto free_bh; } } bridge_pcix_cap = pci_find_capability(bridge, PCI_CAP_ID_PCIX); if (!bridge_pcix_cap) { err = -ENODEV; mthca_err(mdev, "Couldn't locate HCA bridge " "PCI-X capability, aborting.\n"); goto free_bh; } } /* actually hit reset */ { void __iomem *reset = ioremap(pci_resource_start(mdev->pdev, 0) + MTHCA_RESET_OFFSET, 4); if (!reset) { err = -ENOMEM; mthca_err(mdev, "Couldn't map HCA reset register, " "aborting.\n"); goto free_bh; } writel(MTHCA_RESET_VALUE, reset); iounmap(reset); } /* Docs say to wait one second before accessing device */ msleep(1000); /* Now wait for PCI device to start responding again */ { u32 v; int c = 0; for (c = 0; c < 100; ++c) { if (pci_read_config_dword(bridge ? bridge : mdev->pdev, 0, &v)) { err = -ENODEV; mthca_err(mdev, "Couldn't access HCA after reset, " "aborting.\n"); goto free_bh; } if (v != 0xffffffff) goto good; msleep(100); } err = -ENODEV; mthca_err(mdev, "PCI device did not come back after reset, " "aborting.\n"); goto free_bh; } good: /* Now restore the PCI headers */ if (bridge) { if (pci_write_config_dword(bridge, bridge_pcix_cap + 0x8, bridge_header[(bridge_pcix_cap + 0x8) / 4])) { err = -ENODEV; mthca_err(mdev, "Couldn't restore HCA bridge Upstream " "split transaction control, aborting.\n"); goto free_bh; } if (pci_write_config_dword(bridge, bridge_pcix_cap + 0xc, bridge_header[(bridge_pcix_cap + 0xc) / 4])) { err = -ENODEV; mthca_err(mdev, "Couldn't restore HCA bridge Downstream " "split transaction control, aborting.\n"); goto free_bh; } /* * Bridge control register is at 0x3e, so we'll * naturally restore it last in this loop. */ for (i = 0; i < 16; ++i) { if (i * 4 == PCI_COMMAND) continue; if (pci_write_config_dword(bridge, i * 4, bridge_header[i])) { err = -ENODEV; mthca_err(mdev, "Couldn't restore HCA bridge reg %x, " "aborting.\n", i); goto free_bh; } } if (pci_write_config_dword(bridge, PCI_COMMAND, bridge_header[PCI_COMMAND / 4])) { err = -ENODEV; mthca_err(mdev, "Couldn't restore HCA bridge COMMAND, " "aborting.\n"); goto free_bh; } } if (hca_pcix_cap) { if (pci_write_config_dword(mdev->pdev, hca_pcix_cap, hca_header[hca_pcix_cap / 4])) { err = -ENODEV; mthca_err(mdev, "Couldn't restore HCA PCI-X " "command register, aborting.\n"); goto free_bh; } } if (hca_pcie_cap) { devctl = hca_header[(hca_pcie_cap + PCI_EXP_DEVCTL) / 4]; if (pcie_capability_write_word(mdev->pdev, PCI_EXP_DEVCTL, devctl)) { err = -ENODEV; mthca_err(mdev, "Couldn't restore HCA PCI Express " "Device Control register, aborting.\n"); goto free_bh; } linkctl = hca_header[(hca_pcie_cap + PCI_EXP_LNKCTL) / 4]; if (pcie_capability_write_word(mdev->pdev, PCI_EXP_LNKCTL, linkctl)) { err = -ENODEV; mthca_err(mdev, "Couldn't restore HCA PCI Express " "Link control register, aborting.\n"); goto free_bh; } } for (i = 0; i < 16; ++i) { if (i * 4 == PCI_COMMAND) continue; if (pci_write_config_dword(mdev->pdev, i * 4, hca_header[i])) { err = -ENODEV; mthca_err(mdev, "Couldn't restore HCA reg %x, " "aborting.\n", i); goto free_bh; } } if (pci_write_config_dword(mdev->pdev, PCI_COMMAND, hca_header[PCI_COMMAND / 4])) { err = -ENODEV; mthca_err(mdev, "Couldn't restore HCA COMMAND, " "aborting.\n"); } free_bh: kfree(bridge_header); free_hca: kfree(hca_header); put_dev: pci_dev_put(bridge); return err; }
static int __devinit pasemi_nand_probe(struct platform_device *ofdev) { struct pci_dev *pdev; struct device_node *np = ofdev->dev.of_node; struct resource res; struct nand_chip *chip; int err = 0; err = of_address_to_resource(np, 0, &res); if (err) return -EINVAL; /* We only support one device at the moment */ if (pasemi_nand_mtd) return -ENODEV; pr_debug("pasemi_nand at %pR\n", &res); /* Allocate memory for MTD device structure and private data */ pasemi_nand_mtd = kzalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL); if (!pasemi_nand_mtd) { printk(KERN_WARNING "Unable to allocate PASEMI NAND MTD device structure\n"); err = -ENOMEM; goto out; } /* Get pointer to private data */ chip = (struct nand_chip *)&pasemi_nand_mtd[1]; /* Link the private data with the MTD structure */ pasemi_nand_mtd->priv = chip; pasemi_nand_mtd->owner = THIS_MODULE; chip->IO_ADDR_R = of_iomap(np, 0); chip->IO_ADDR_W = chip->IO_ADDR_R; if (!chip->IO_ADDR_R) { err = -EIO; goto out_mtd; } pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa008, NULL); if (!pdev) { err = -ENODEV; goto out_ior; } lpcctl = pci_resource_start(pdev, 0); pci_dev_put(pdev); if (!request_region(lpcctl, 4, driver_name)) { err = -EBUSY; goto out_ior; } chip->cmd_ctrl = pasemi_hwcontrol; chip->dev_ready = pasemi_device_ready; chip->read_buf = pasemi_read_buf; chip->write_buf = pasemi_write_buf; chip->chip_delay = 0; chip->ecc.mode = NAND_ECC_SOFT; /* Enable the following for a flash based bad block table */ chip->bbt_options = NAND_BBT_USE_FLASH; /* Scan to find existence of the device */ if (nand_scan(pasemi_nand_mtd, 1)) { err = -ENXIO; goto out_lpc; } if (mtd_device_register(pasemi_nand_mtd, NULL, 0)) { printk(KERN_ERR "pasemi_nand: Unable to register MTD device\n"); err = -ENODEV; goto out_lpc; } printk(KERN_INFO "PA Semi NAND flash at %08llx, control at I/O %x\n", res.start, lpcctl); return 0; out_lpc: release_region(lpcctl, 4); out_ior: iounmap(chip->IO_ADDR_R); out_mtd: kfree(pasemi_nand_mtd); out: return err; }
static int malo_pci_attach(device_t dev) { int error = ENXIO, i, msic, reg; struct malo_pci_softc *psc = device_get_softc(dev); struct malo_softc *sc = &psc->malo_sc; sc->malo_dev = dev; pci_enable_busmaster(dev); /* * Setup memory-mapping of PCI registers. */ psc->malo_mem_spec = malo_res_spec_mem; error = bus_alloc_resources(dev, psc->malo_mem_spec, psc->malo_res_mem); if (error) { device_printf(dev, "couldn't allocate memory resources\n"); return (ENXIO); } /* * Arrange and allocate interrupt line. */ sc->malo_invalid = 1; if (pci_find_cap(dev, PCIY_EXPRESS, ®) == 0) { msic = pci_msi_count(dev); if (bootverbose) device_printf(dev, "MSI count : %d\n", msic); } else msic = 0; psc->malo_irq_spec = malo_res_spec_legacy; if (msic == MALO_MSI_MESSAGES && msi_disable == 0) { if (pci_alloc_msi(dev, &msic) == 0) { if (msic == MALO_MSI_MESSAGES) { device_printf(dev, "Using %d MSI messages\n", msic); psc->malo_irq_spec = malo_res_spec_msi; psc->malo_msi = 1; } else pci_release_msi(dev); } } error = bus_alloc_resources(dev, psc->malo_irq_spec, psc->malo_res_irq); if (error) { device_printf(dev, "couldn't allocate IRQ resources\n"); goto bad; } if (psc->malo_msi == 0) error = bus_setup_intr(dev, psc->malo_res_irq[0], INTR_TYPE_NET | INTR_MPSAFE, malo_intr, NULL, sc, &psc->malo_intrhand[0]); else { for (i = 0; i < MALO_MSI_MESSAGES; i++) { error = bus_setup_intr(dev, psc->malo_res_irq[i], INTR_TYPE_NET | INTR_MPSAFE, malo_intr, NULL, sc, &psc->malo_intrhand[i]); if (error != 0) break; } } /* * Setup DMA descriptor area. */ if (bus_dma_tag_create(bus_get_dma_tag(dev), /* parent */ 1, 0, /* alignment, bounds */ BUS_SPACE_MAXADDR_32BIT, /* lowaddr */ BUS_SPACE_MAXADDR, /* highaddr */ NULL, NULL, /* filter, filterarg */ BUS_SPACE_MAXADDR, /* maxsize */ 0, /* nsegments */ BUS_SPACE_MAXADDR, /* maxsegsize */ 0, /* flags */ NULL, /* lockfunc */ NULL, /* lockarg */ &sc->malo_dmat)) { device_printf(dev, "cannot allocate DMA tag\n"); goto bad1; } sc->malo_io0t = rman_get_bustag(psc->malo_res_mem[0]); sc->malo_io0h = rman_get_bushandle(psc->malo_res_mem[0]); sc->malo_io1t = rman_get_bustag(psc->malo_res_mem[1]); sc->malo_io1h = rman_get_bushandle(psc->malo_res_mem[1]); error = malo_attach(pci_get_device(dev), sc); if (error != 0) goto bad2; return (error); bad2: bus_dma_tag_destroy(sc->malo_dmat); bad1: if (psc->malo_msi == 0) bus_teardown_intr(dev, psc->malo_res_irq[0], psc->malo_intrhand[0]); else { for (i = 0; i < MALO_MSI_MESSAGES; i++) bus_teardown_intr(dev, psc->malo_res_irq[i], psc->malo_intrhand[i]); } bus_release_resources(dev, psc->malo_irq_spec, psc->malo_res_irq); bad: if (psc->malo_msi != 0) pci_release_msi(dev); bus_release_resources(dev, psc->malo_mem_spec, psc->malo_res_mem); return (error); }
int usb_amd_find_chipset_info(void) { unsigned long flags; struct amd_chipset_info info; int ret; spin_lock_irqsave(&amd_lock, flags); /* probe only once */ if (amd_chipset.probe_count > 0) { amd_chipset.probe_count++; spin_unlock_irqrestore(&amd_lock, flags); return amd_chipset.probe_result; } memset(&info, 0, sizeof(info)); spin_unlock_irqrestore(&amd_lock, flags); if (!amd_chipset_sb_type_init(&info)) { ret = 0; goto commit; } /* Below chipset generations needn't enable AMD PLL quirk */ if (info.sb_type.gen == AMD_CHIPSET_UNKNOWN || info.sb_type.gen == AMD_CHIPSET_SB600 || info.sb_type.gen == AMD_CHIPSET_YANGTZE || (info.sb_type.gen == AMD_CHIPSET_SB700 && info.sb_type.rev > 0x3b)) { if (info.smbus_dev) { pci_dev_put(info.smbus_dev); info.smbus_dev = NULL; } ret = 0; goto commit; } info.nb_dev = pci_get_device(PCI_VENDOR_ID_AMD, 0x9601, NULL); if (info.nb_dev) { info.nb_type = 1; } else { info.nb_dev = pci_get_device(PCI_VENDOR_ID_AMD, 0x1510, NULL); if (info.nb_dev) { info.nb_type = 2; } else { info.nb_dev = pci_get_device(PCI_VENDOR_ID_AMD, 0x9600, NULL); if (info.nb_dev) info.nb_type = 3; } } ret = info.probe_result = 1; printk(KERN_DEBUG "QUIRK: Enable AMD PLL fix\n"); commit: spin_lock_irqsave(&amd_lock, flags); if (amd_chipset.probe_count > 0) { /* race - someone else was faster - drop devices */ /* Mark that we where here */ amd_chipset.probe_count++; ret = amd_chipset.probe_result; spin_unlock_irqrestore(&amd_lock, flags); pci_dev_put(info.nb_dev); pci_dev_put(info.smbus_dev); } else { /* no race - commit the result */ info.probe_count++; amd_chipset = info; spin_unlock_irqrestore(&amd_lock, flags); } return ret; }
static int amd8111_dev_probe(struct pci_dev *dev, const struct pci_device_id *id) { struct amd8111_dev_info *dev_info = &amd8111_devices[id->driver_data]; dev_info->dev = pci_get_device(PCI_VENDOR_ID_AMD, dev_info->err_dev, NULL); if (!dev_info->dev) { printk(KERN_ERR "EDAC device not found:" "vendor %x, device %x, name %s\n", PCI_VENDOR_ID_AMD, dev_info->err_dev, dev_info->ctl_name); return -ENODEV; } if (pci_enable_device(dev_info->dev)) { pci_dev_put(dev_info->dev); printk(KERN_ERR "failed to enable:" "vendor %x, device %x, name %s\n", PCI_VENDOR_ID_AMD, dev_info->err_dev, dev_info->ctl_name); return -ENODEV; } /* * we do not allocate extra private structure for * edac_device_ctl_info, but make use of existing * one instead. */ dev_info->edac_idx = edac_device_alloc_index(); dev_info->edac_dev = edac_device_alloc_ctl_info(0, dev_info->ctl_name, 1, NULL, 0, 0, NULL, 0, dev_info->edac_idx); if (!dev_info->edac_dev) return -ENOMEM; dev_info->edac_dev->pvt_info = dev_info; dev_info->edac_dev->dev = &dev_info->dev->dev; dev_info->edac_dev->mod_name = AMD8111_EDAC_MOD_STR; dev_info->edac_dev->ctl_name = dev_info->ctl_name; dev_info->edac_dev->dev_name = dev_name(&dev_info->dev->dev); if (edac_op_state == EDAC_OPSTATE_POLL) dev_info->edac_dev->edac_check = dev_info->check; if (dev_info->init) dev_info->init(dev_info); if (edac_device_add_device(dev_info->edac_dev) > 0) { printk(KERN_ERR "failed to add edac_dev for %s\n", dev_info->ctl_name); edac_device_free_ctl_info(dev_info->edac_dev); return -ENODEV; } printk(KERN_INFO "added one edac_dev on AMD8111 " "vendor %x, device %x, name %s\n", PCI_VENDOR_ID_AMD, dev_info->err_dev, dev_info->ctl_name); return 0; }
static long ali_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { void __user *argp = (void __user *)arg; int __user *p = argp; static const struct watchdog_info ident = { .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, .firmware_version = 0, .identity = "ALi M1535 WatchDog Timer", }; switch (cmd) { case WDIOC_GETSUPPORT: return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; case WDIOC_GETSTATUS: case WDIOC_GETBOOTSTATUS: return put_user(0, p); case WDIOC_SETOPTIONS: { int new_options, retval = -EINVAL; if (get_user(new_options, p)) return -EFAULT; if (new_options & WDIOS_DISABLECARD) { ali_stop(); retval = 0; } if (new_options & WDIOS_ENABLECARD) { ali_start(); retval = 0; } return retval; } case WDIOC_KEEPALIVE: ali_keepalive(); return 0; case WDIOC_SETTIMEOUT: { int new_timeout; if (get_user(new_timeout, p)) return -EFAULT; if (ali_settimer(new_timeout)) return -EINVAL; ali_keepalive(); /* Fall */ } case WDIOC_GETTIMEOUT: return put_user(timeout, p); default: return -ENOTTY; } } /* * ali_open - handle open of ali watchdog * @inode: inode from VFS * @file: file from VFS * * Open the ALi watchdog device. Ensure only one person opens it * at a time. Also start the watchdog running. */ static int ali_open(struct inode *inode, struct file *file) { /* /dev/watchdog can only be opened once */ if (test_and_set_bit(0, &ali_is_open)) return -EBUSY; /* Activate */ ali_start(); return nonseekable_open(inode, file); } /* * ali_release - close an ALi watchdog * @inode: inode from VFS * @file: file from VFS * * Close the ALi watchdog device. Actual shutdown of the timer * only occurs if the magic sequence has been set. */ static int ali_release(struct inode *inode, struct file *file) { /* * Shut off the timer. */ if (ali_expect_release == 42) ali_stop(); else { pr_crit("Unexpected close, not stopping watchdog!\n"); ali_keepalive(); } clear_bit(0, &ali_is_open); ali_expect_release = 0; return 0; } /* * ali_notify_sys - System down notifier * * Notifier for system down */ static int ali_notify_sys(struct notifier_block *this, unsigned long code, void *unused) { if (code == SYS_DOWN || code == SYS_HALT) ali_stop(); /* Turn the WDT off */ return NOTIFY_DONE; } /* * Data for PCI driver interface * * This data only exists for exporting the supported * PCI ids via MODULE_DEVICE_TABLE. We do not actually * register a pci_driver, because someone else might one day * want to register another driver on the same PCI id. */ static DEFINE_PCI_DEVICE_TABLE(ali_pci_tbl) __used = { { PCI_VENDOR_ID_AL, 0x1533, PCI_ANY_ID, PCI_ANY_ID,}, { PCI_VENDOR_ID_AL, 0x1535, PCI_ANY_ID, PCI_ANY_ID,}, { 0, }, }; MODULE_DEVICE_TABLE(pci, ali_pci_tbl); /* * ali_find_watchdog - find a 1535 and 7101 * * Scans the PCI hardware for a 1535 series bridge and matching 7101 * watchdog device. This may be overtight but it is better to be safe */ static int __init ali_find_watchdog(void) { struct pci_dev *pdev; u32 wdog; /* Check for a 1533/1535 series bridge */ pdev = pci_get_device(PCI_VENDOR_ID_AL, 0x1535, NULL); if (pdev == NULL) pdev = pci_get_device(PCI_VENDOR_ID_AL, 0x1533, NULL); if (pdev == NULL) return -ENODEV; pci_dev_put(pdev); /* Check for the a 7101 PMU */ pdev = pci_get_device(PCI_VENDOR_ID_AL, 0x7101, NULL); if (pdev == NULL) return -ENODEV; if (pci_enable_device(pdev)) { pci_dev_put(pdev); return -EIO; } ali_pci = pdev; /* * Initialize the timer bits */ pci_read_config_dword(pdev, 0xCC, &wdog); /* Timer bits */ wdog &= ~0x3F; /* Issued events */ wdog &= ~((1 << 27)|(1 << 26)|(1 << 25)|(1 << 24)); /* No monitor bits */ wdog &= ~((1 << 16)|(1 << 13)|(1 << 12)|(1 << 11)|(1 << 10)|(1 << 9)); pci_write_config_dword(pdev, 0xCC, wdog); return 0; } /* * Kernel Interfaces */ static const struct file_operations ali_fops = { .owner = THIS_MODULE, .llseek = no_llseek, .write = ali_write, .unlocked_ioctl = ali_ioctl, .open = ali_open, .release = ali_release, }; static struct miscdevice ali_miscdev = { .minor = WATCHDOG_MINOR, .name = "watchdog", .fops = &ali_fops, }; static struct notifier_block ali_notifier = { .notifier_call = ali_notify_sys, }; /* * watchdog_init - module initialiser * * Scan for a suitable watchdog and if so initialize it. Return an error * if we cannot, the error causes the module to unload */ static int __init watchdog_init(void) { int ret; /* Check whether or not the hardware watchdog is there */ if (ali_find_watchdog() != 0) return -ENODEV; /* Check that the timeout value is within it's range; if not reset to the default */ if (timeout < 1 || timeout >= 18000) { timeout = WATCHDOG_TIMEOUT; pr_info("timeout value must be 0 < timeout < 18000, using %d\n", timeout); } /* Calculate the watchdog's timeout */ ali_settimer(timeout); ret = register_reboot_notifier(&ali_notifier); if (ret != 0) { pr_err("cannot register reboot notifier (err=%d)\n", ret); goto out; } ret = misc_register(&ali_miscdev); if (ret != 0) { pr_err("cannot register miscdev on minor=%d (err=%d)\n", WATCHDOG_MINOR, ret); goto unreg_reboot; } pr_info("initialized. timeout=%d sec (nowayout=%d)\n", timeout, nowayout); out: return ret; unreg_reboot: unregister_reboot_notifier(&ali_notifier); goto out; } /* * watchdog_exit - module de-initialiser * * Called while unloading a successfully installed watchdog module. */ static void __exit watchdog_exit(void) { /* Stop the timer before we leave */ ali_stop(); /* Deregister */ misc_deregister(&ali_miscdev); unregister_reboot_notifier(&ali_notifier); pci_dev_put(ali_pci); }