Exemplo n.º 1
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_TXSTATUS_LOCK_DESTROY(sc);
	ATH_RX_LOCK_DESTROY(sc);
	ATH_TX_LOCK_DESTROY(sc);
	ATH_TX_IC_LOCK_DESTROY(sc);
	ATH_PCU_LOCK_DESTROY(sc);
	ATH_LOCK_DESTROY(sc);

	return (0);
}
Exemplo n.º 2
0
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);

	if (sc->sc_eepromdata)
		free(sc->sc_eepromdata, M_TEMP);

	ATH_TXSTATUS_LOCK_DESTROY(sc);
	ATH_PCU_LOCK_DESTROY(sc);
	ATH_RX_LOCK_DESTROY(sc);
	ATH_TX_LOCK_DESTROY(sc);
	ATH_LOCK_DESTROY(sc);

	return (0);
}
Exemplo n.º 3
0
static int
ath_ahb_attach(device_t dev)
{
	struct ath_ahb_softc *psc = device_get_softc(dev);
	struct ath_softc *sc = &psc->sc_sc;
	int error = ENXIO;
	int rid;
	long eepromaddr;
	int eepromsize;
	uint8_t *p;
	int device_id, vendor_id;

	sc->sc_dev = dev;

	rid = 0;
	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;
	}

	if (resource_long_value(device_get_name(dev), device_get_unit(dev),
	    "eepromaddr", &eepromaddr) != 0) {
		device_printf(dev, "cannot fetch 'eepromaddr' from hints\n");
		goto bad0;
	}

	/*
	 * The default EEPROM size is 2048 * 16 bit words.
	 * Later EEPROM/OTP/flash regions may be quite a bit bigger.
	 */
	if (resource_int_value(device_get_name(dev), device_get_unit(dev),
	    "eepromsize", &eepromsize) != 0) {
		eepromsize = ATH_EEPROM_DATA_SIZE * 2;
	}


	rid = 0;
	device_printf(sc->sc_dev, "eeprom @ %p (%d bytes)\n",
	    (void *) eepromaddr, eepromsize);
	psc->sc_eeprom = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, (uintptr_t) eepromaddr,
	  (uintptr_t) eepromaddr + (uintptr_t) (eepromsize - 1), 0, RF_ACTIVE);
	if (psc->sc_eeprom == NULL) {
		device_printf(dev, "cannot map eeprom space\n");
		goto bad0;
	}

	/* 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;

	/* Copy the EEPROM data out */
	sc->sc_eepromdata = malloc(eepromsize, M_TEMP, M_NOWAIT | M_ZERO);
	if (sc->sc_eepromdata == NULL) {
		device_printf(dev, "cannot allocate memory for eeprom data\n");
		goto bad1;
	}
	device_printf(sc->sc_dev, "eeprom data @ %p\n", (void *) rman_get_bushandle(psc->sc_eeprom));
	/* XXX why doesn't this work? -adrian */
#if 0
	bus_space_read_multi_1(
	    rman_get_bustag(psc->sc_eeprom),
	    rman_get_bushandle(psc->sc_eeprom),
	    0, (u_int8_t *) sc->sc_eepromdata, eepromsize);
#endif
	p = (void *) rman_get_bushandle(psc->sc_eeprom);
	memcpy(sc->sc_eepromdata, p, eepromsize);

	/*
	 * 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;
	}

	/*
	 * Check if a device/vendor ID is provided in hints.
	 */
	if (resource_int_value(device_get_name(dev), device_get_unit(dev),
	    "vendor_id", &vendor_id) != 0) {
		vendor_id = VENDOR_ATHEROS;
	}

	if (resource_int_value(device_get_name(dev), device_get_unit(dev),
	    "device_id", &device_id) != 0) {
		device_id = AR9130_DEVID;
	}

	ATH_LOCK_INIT(sc);
	ATH_PCU_LOCK_INIT(sc);
	ATH_RX_LOCK_INIT(sc);
	ATH_TX_LOCK_INIT(sc);
	ATH_TX_IC_LOCK_INIT(sc);
	ATH_TXSTATUS_LOCK_INIT(sc);

	error = ath_attach(device_id, sc);
	if (error == 0)					/* success */
		return 0;

	ATH_TXSTATUS_LOCK_DESTROY(sc);
	ATH_RX_LOCK_DESTROY(sc);
	ATH_TX_LOCK_DESTROY(sc);
	ATH_TX_IC_LOCK_DESTROY(sc);
	ATH_PCU_LOCK_DESTROY(sc);
	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, 0, psc->sc_eeprom);
bad0:
	bus_release_resource(dev, SYS_RES_MEMORY, 0, psc->sc_sr);
bad:
	/* XXX?! */
	if (sc->sc_eepromdata)
		free(sc->sc_eepromdata, M_TEMP);
	return (error);
}
Exemplo n.º 4
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;
#ifdef	ATH_EEPROM_FIRMWARE
	const struct firmware *fw = NULL;
	const char *buf;
#endif
	const struct pci_device_id *pd;

	sc->sc_dev = dev;

	/* Do this lookup anyway; figure out what to do with it later */
	pd = ath_pci_probe_device(dev, ath_pci_id_table, nitems(ath_pci_id_table));
	if (pd)
		sc->sc_pci_devinfo = pd->driver_data;

	/*
	 * Enable bus mastering.
	 */
	pci_enable_busmaster(dev);

	/*
	 * Setup other PCI bus configuration parameters.
	 */
	ath_pci_setup(dev);

	/*
	 * 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;
	}
	sc->sc_st = (HAL_BUS_TAG) 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;

	ATH_LOCK_INIT(sc);
	ATH_PCU_LOCK_INIT(sc);
	ATH_RX_LOCK_INIT(sc);
	ATH_TX_LOCK_INIT(sc);
	ATH_TXSTATUS_LOCK_INIT(sc);

	/*
	 * 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;
	}

#ifdef	ATH_EEPROM_FIRMWARE
	/*
	 * If there's an EEPROM firmware image, load that in.
	 */
	if (resource_string_value(device_get_name(dev), device_get_unit(dev),
	    "eeprom_firmware", &buf) == 0) {
		if (bootverbose)
			device_printf(dev, "%s: looking up firmware @ '%s'\n",
			    __func__, buf);

		fw = firmware_get(buf);
		if (fw == NULL) {
			device_printf(dev, "%s: couldn't find firmware\n",
			    __func__);
			goto bad4;
		}

		device_printf(dev, "%s: EEPROM firmware @ %p\n",
		    __func__, fw->data);
		sc->sc_eepromdata =
		    malloc(fw->datasize, M_TEMP, M_WAITOK | M_ZERO);
		if (! sc->sc_eepromdata) {
			device_printf(dev, "%s: can't malloc eepromdata\n",
			    __func__);
			goto bad4;
		}
		memcpy(sc->sc_eepromdata, fw->data, fw->datasize);
		firmware_put(fw, 0);
	}
#endif /* ATH_EEPROM_FIRMWARE */

	error = ath_attach(pci_get_device(dev), sc);
	if (error == 0)					/* success */
		return 0;

#ifdef	ATH_EEPROM_FIRMWARE
bad4:
#endif
	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);

	ATH_TXSTATUS_LOCK_DESTROY(sc);
	ATH_PCU_LOCK_DESTROY(sc);
	ATH_RX_LOCK_DESTROY(sc);
	ATH_TX_LOCK_DESTROY(sc);
	ATH_LOCK_DESTROY(sc);

bad:
	return (error);
}