static int ath_pci_detach(device_t dev) { struct ath_pci_softc *psc = device_get_softc(dev); struct ath_softc *sc = &psc->sc_sc; /* check if device was removed */ sc->sc_invalid = !bus_child_present(dev); /* * Do a config read to clear pre-existing pci error status. */ (void) pci_read_config(dev, PCIR_COMMAND, 4); ath_detach(sc); bus_generic_detach(dev); bus_teardown_intr(dev, psc->sc_irq, psc->sc_ih); bus_release_resource(dev, SYS_RES_IRQ, 0, psc->sc_irq); bus_dma_tag_destroy(sc->sc_dmat); bus_release_resource(dev, SYS_RES_MEMORY, BS_BAR, psc->sc_sr); ATH_LOCK_DESTROY(sc); return (0); }
static int ath_ahb_detach(device_t dev) { struct ath_ahb_softc *psc = device_get_softc(dev); struct ath_softc *sc = &psc->sc_sc; /* check if device was removed */ sc->sc_invalid = !bus_child_present(dev); ath_detach(sc); bus_generic_detach(dev); bus_teardown_intr(dev, psc->sc_irq, psc->sc_ih); bus_release_resource(dev, SYS_RES_IRQ, 0, psc->sc_irq); bus_dma_tag_destroy(sc->sc_dmat); bus_release_resource(dev, SYS_RES_MEMORY, 0, psc->sc_sr); bus_release_resource(dev, SYS_RES_MEMORY, 0, psc->sc_eeprom); /* XXX?! */ if (sc->sc_eepromdata) free(sc->sc_eepromdata, M_TEMP); ATH_LOCK_DESTROY(sc); return (0); }
static void ath_pci_remove(adf_drv_handle_t hdl) { struct ath_softc_tgt *sc = hdl; ath_detach((struct ath_softc_tgt *)hdl); adf_os_free_intr(sc->sc_dev); }
int ath_pci_detach(struct device *self, int flags) { struct ath_pci_softc *psc = (struct ath_pci_softc *)self; struct ath_softc *sc = &psc->sc_sc; ath_detach(&psc->sc_sc, flags); if (psc->sc_ih != NULL) { pci_intr_disestablish(psc->sc_pc, psc->sc_ih); psc->sc_ih = NULL; } if (sc->sc_ss != 0) { bus_space_unmap(sc->sc_st, sc->sc_sh, sc->sc_ss); sc->sc_ss = 0; } return (0); }
static int exit_ath_wmac(u_int16_t wlanNum, struct ar531x_config *config) { struct ath_ahb_softc *sc = sclist[wlanNum]; struct net_device *dev; u_int16_t devid; if (sc == NULL) return -ENODEV; /* XXX: correct return value? */ dev = sc->aps_sc.sc_dev; ath_detach(dev); if (dev->irq) free_irq(dev->irq, dev); devid = sc->aps_sc.devid; config->tag = (void *)((unsigned long) devid); ahb_disable_wmac(devid, wlanNum); free_netdev(dev); sclist[wlanNum] = NULL; return 0; }
int ath_cardbus_detach(device_t self, int flags) { struct ath_cardbus_softc *csc = device_private(self); struct ath_softc *sc = &csc->sc_ath; struct cardbus_devfunc *ct = csc->sc_ct; int rv; #if defined(DIAGNOSTIC) if (ct == NULL) panic("%s: data structure lacks", device_xname(sc->sc_dev)); #endif rv = ath_detach(sc); if (rv) return (rv); pmf_device_deregister(self); /* * Unhook the interrupt handler. */ if (csc->sc_ih != NULL) { cardbus_intr_disestablish(ct->ct_cc, ct->ct_cf, csc->sc_ih); csc->sc_ih = NULL; } /* * Release bus space and close window. */ Cardbus_mapreg_unmap(ct, ATH_PCI_MMBA, csc->sc_iot, csc->sc_ioh, csc->sc_mapsize); ATH_LOCK_DESTROY(sc); return (0); }
static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) { void __iomem *mem; struct ath_wiphy *aphy; struct ath_softc *sc; struct ieee80211_hw *hw; u8 csz; u16 subsysid; u32 val; int ret = 0; struct ath_hw *ah; char hw_name[64]; if (pci_enable_device(pdev)) return -EIO; ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); if (ret) { printk(KERN_ERR "ath9k: 32-bit DMA not available\n"); goto bad; } ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); if (ret) { printk(KERN_ERR "ath9k: 32-bit DMA consistent " "DMA enable failed\n"); goto bad; } /* * Cache line size is used to size and align various * structures used to communicate with the hardware. */ pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &csz); if (csz == 0) { /* * Linux 2.4.18 (at least) writes the cache line size * register as a 16-bit wide register which is wrong. * We must have this setup properly for rx buffer * DMA to work so force a reasonable value here if it * comes up zero. */ csz = L1_CACHE_BYTES / sizeof(u32); pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, csz); } /* * The default setting of latency timer yields poor results, * set it to the value used by other systems. It may be worth * tweaking this setting more. */ pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xa8); pci_set_master(pdev); /* * Disable the RETRY_TIMEOUT register (0x41) to keep * PCI Tx retries from interfering with C3 CPU state. */ pci_read_config_dword(pdev, 0x40, &val); if ((val & 0x0000ff00) != 0) pci_write_config_dword(pdev, 0x40, val & 0xffff00ff); ret = pci_request_region(pdev, 0, "ath9k"); if (ret) { dev_err(&pdev->dev, "PCI memory region reserve error\n"); ret = -ENODEV; goto bad; } mem = pci_iomap(pdev, 0, 0); if (!mem) { printk(KERN_ERR "PCI memory map error\n") ; ret = -EIO; goto bad1; } hw = ieee80211_alloc_hw(sizeof(struct ath_wiphy) + sizeof(struct ath_softc), &ath9k_ops); if (!hw) { dev_err(&pdev->dev, "no memory for ieee80211_hw\n"); ret = -ENOMEM; goto bad2; } SET_IEEE80211_DEV(hw, &pdev->dev); pci_set_drvdata(pdev, hw); aphy = hw->priv; sc = (struct ath_softc *) (aphy + 1); aphy->sc = sc; aphy->hw = hw; sc->pri_wiphy = aphy; sc->hw = hw; sc->dev = &pdev->dev; sc->mem = mem; pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &subsysid); ret = ath_init_device(id->device, sc, subsysid, &ath_pci_bus_ops); if (ret) { dev_err(&pdev->dev, "failed to initialize device\n"); goto bad3; } /* setup interrupt service routine */ ret = request_irq(pdev->irq, ath_isr, IRQF_SHARED, "ath9k", sc); if (ret) { dev_err(&pdev->dev, "request_irq failed\n"); goto bad4; } sc->irq = pdev->irq; ah = sc->sc_ah; ath9k_hw_name(ah, hw_name, sizeof(hw_name)); printk(KERN_INFO "%s: %s mem=0x%lx, irq=%d\n", wiphy_name(hw->wiphy), hw_name, (unsigned long)mem, pdev->irq); return 0; bad4: ath_detach(sc); bad3: ieee80211_free_hw(hw); bad2: pci_iounmap(pdev, mem); bad1: pci_release_region(pdev, 0); bad: pci_disable_device(pdev); return ret; }