예제 #1
0
int
ata_identify(device_t dev)
{
    struct ata_channel *ch = device_get_softc(dev);
    struct ata_device *master = NULL, *slave = NULL;
    device_t master_child = NULL, slave_child = NULL;
    int master_unit = -1, slave_unit = -1;

    if (ch->devices & (ATA_ATA_MASTER | ATA_ATAPI_MASTER)) {
	if (!(master = kmalloc(sizeof(struct ata_device),
			      M_ATA, M_INTWAIT | M_ZERO))) {
	    device_printf(dev, "out of memory\n");
	    return ENOMEM;
	}
	master->unit = ATA_MASTER;
    }
    if (ch->devices & (ATA_ATA_SLAVE | ATA_ATAPI_SLAVE)) {
	if (!(slave = kmalloc(sizeof(struct ata_device),
			     M_ATA, M_INTWAIT | M_ZERO))) {
	    kfree(master, M_ATA);
	    device_printf(dev, "out of memory\n");
	    return ENOMEM;
	}
	slave->unit = ATA_SLAVE;
    }

#ifdef ATA_STATIC_ID
    if (ch->devices & ATA_ATA_MASTER)
	master_unit = (device_get_unit(dev) << 1);
#endif
    if (master && !(master_child = ata_add_child(dev, master, master_unit))) {
	kfree(master, M_ATA);
	master = NULL;
    }
#ifdef ATA_STATIC_ID
    if (ch->devices & ATA_ATA_SLAVE)
	slave_unit = (device_get_unit(dev) << 1) + 1;
#endif
    if (slave && !(slave_child = ata_add_child(dev, slave, slave_unit))) {
	kfree(slave, M_ATA);
	slave = NULL;
    }

    if (slave && ata_getparam(slave, 1)) {
	device_delete_child(dev, slave_child);
	kfree(slave, M_ATA);
    }
    if (master && ata_getparam(master, 1)) {
	device_delete_child(dev, master_child);
	kfree(master, M_ATA);
    }

    bus_generic_probe(dev);
    bus_generic_attach(dev);
    return 0;
}
예제 #2
0
파일: sbc.c 프로젝트: edgar-pek/PerspicuOS
static int
sbc_detach(device_t dev)
{
	struct sbc_softc *scp = device_get_softc(dev);

	sbc_lock(scp);
	device_delete_child(dev, scp->child_midi2);
	device_delete_child(dev, scp->child_midi1);
	device_delete_child(dev, scp->child_pcm);
	release_resource(scp);
	sbc_lockdestroy(scp);
	return bus_generic_detach(dev);
}
예제 #3
0
static void
card_detect_task(void *arg, int pending)
{
	struct fsl_sdhc_softc *sc = (struct fsl_sdhc_softc *)arg;
	int err;
	int insert;

	insert = read4(sc, SDHC_PRSSTAT) & PRSSTAT_CINS;

	mtx_lock(&sc->mtx);

	if (insert) {
		if (sc->child != NULL) {
			mtx_unlock(&sc->mtx);
			return;
		}

		sc->child = device_add_child(sc->self, "mmc", -1);
		if (sc->child == NULL) {
			device_printf(sc->self, "Couldn't add MMC bus!\n");
			mtx_unlock(&sc->mtx);
			return;
		}

		/* Initialize MMC bus host structure. */
		init_mmc_host_struct(sc);
		device_set_ivars(sc->child, &sc->mmc_host);

	} else {
		if (sc->child == NULL) {
			mtx_unlock(&sc->mtx);
			return;
		}
	}

	mtx_unlock(&sc->mtx);

	if (insert) {
		if ((err = device_probe_and_attach(sc->child)) != 0) {
			device_printf(sc->self, "MMC bus failed on probe "
			    "and attach! error %d\n", err);
			device_delete_child(sc->self, sc->child);
			sc->child = NULL;
		}
	} else {
		if (device_delete_child(sc->self, sc->child) != 0)
			device_printf(sc->self, "Could not delete MMC bus!\n");
		sc->child = NULL;
	}
}
예제 #4
0
static int
coremctl_detach(device_t dev)
{
    struct coremctl_softc *sc = device_get_softc(dev);

    if (sc->sc_ecc != NULL)
        device_delete_child(dev, sc->sc_ecc);
    if (sc->sc_temp != NULL)
        device_delete_child(dev, sc->sc_temp);
    bus_generic_detach(dev);

    if (sc->sc_mch != NULL)
        pmap_unmapdev((vm_offset_t)sc->sc_mch, MCH_CORE_SIZE);
    return 0;
}
예제 #5
0
int
ata_detach(device_t dev)
{
    struct ata_channel *ch = device_get_softc(dev);
    device_t *children;
    int nchildren, i;

    /* check that we have a valid channel to detach */
    if (!ch->r_irq)
	return ENXIO;

    /* grap the channel lock so no new requests gets launched */
    mtx_lock(&ch->state_mtx);
    ch->state |= ATA_STALL_QUEUE;
    mtx_unlock(&ch->state_mtx);

    /* detach & delete all children */
    if (!device_get_children(dev, &children, &nchildren)) {
	for (i = 0; i < nchildren; i++)
	    if (children[i])
		device_delete_child(dev, children[i]);
	free(children, M_TEMP);
    } 

    /* release resources */
    bus_teardown_intr(dev, ch->r_irq, ch->ih);
    bus_release_resource(dev, SYS_RES_IRQ, ATA_IRQ_RID, ch->r_irq);
    ch->r_irq = NULL;
    mtx_destroy(&ch->state_mtx);
    mtx_destroy(&ch->queue_mtx);
    return 0;
}
예제 #6
0
static int
mvs_detach(device_t dev)
{
	struct mvs_controller *ctlr = device_get_softc(dev);
	device_t *children;
	int nchildren, i;

	/* Detach & delete all children */
	if (!device_get_children(dev, &children, &nchildren)) {
		for (i = 0; i < nchildren; i++)
			device_delete_child(dev, children[i]);
		free(children, M_TEMP);
	}
	/* Free interrupt. */
	if (ctlr->irq.r_irq) {
		bus_teardown_intr(dev, ctlr->irq.r_irq,
		    ctlr->irq.handle);
		bus_release_resource(dev, SYS_RES_IRQ,
		    ctlr->irq.r_irq_rid, ctlr->irq.r_irq);
	}
	/* Free memory. */
	rman_fini(&ctlr->sc_iomem);
	if (ctlr->r_mem)
		bus_release_resource(dev, SYS_RES_MEMORY, ctlr->r_rid, ctlr->r_mem);
	mtx_destroy(&ctlr->mtx);
	return (0);
}
예제 #7
0
파일: virtio_pci.c 프로젝트: 2asoft/freebsd
static int
vtpci_detach(device_t dev)
{
	struct vtpci_softc *sc;
	device_t child;
	int error;

	sc = device_get_softc(dev);

	if ((child = sc->vtpci_child_dev) != NULL) {
		error = device_delete_child(dev, child);
		if (error)
			return (error);
		sc->vtpci_child_dev = NULL;
	}

	vtpci_reset(sc);

	if (sc->vtpci_msix_res != NULL) {
		bus_release_resource(dev, SYS_RES_MEMORY, PCIR_BAR(1),
		    sc->vtpci_msix_res);
		sc->vtpci_msix_res = NULL;
	}

	if (sc->vtpci_res != NULL) {
		bus_release_resource(dev, SYS_RES_IOPORT, PCIR_BAR(0),
		    sc->vtpci_res);
		sc->vtpci_res = NULL;
	}

	return (0);
}
예제 #8
0
파일: nandsim.c 프로젝트: 2asoft/freebsd
static int
nandsim_stop_ctrl(int num)
{
	device_t nexus;
	devclass_t nexus_devclass;
	int ret = 0;

	nand_debug(NDBG_SIM,"stop controller num:%d", num);

	if (num >= MAX_SIM_DEV) {
		return (EINVAL);
	}

	if (!ctrls[num].created || !ctrls[num].running) {
		return (ENODEV);
	}

	/* We will add our device as a child of the nexus0 device */
	if (!(nexus_devclass = devclass_find("nexus")) ||
	    !(nexus = devclass_get_device(nexus_devclass, 0))) {
		return (ENODEV);
	}

	mtx_lock(&Giant);
	if (ctrls[num].sim_ctrl_dev) {
		ret = device_delete_child(nexus, ctrls[num].sim_ctrl_dev);
		ctrls[num].sim_ctrl_dev = NULL;
	}
	mtx_unlock(&Giant);

	ctrls[num].running = 0;

	return (ret);
}
예제 #9
0
static device_t
ofw_iicbus_add_child(device_t dev, u_int order, const char *name, int unit)
{
	device_t child;
	struct ofw_iicbus_devinfo *devi;

	child = device_add_child_ordered(dev, order, name, unit);
	if (child == NULL)
		return (child);
	devi = malloc(sizeof(struct ofw_iicbus_devinfo), M_DEVBUF,
	    M_NOWAIT | M_ZERO);
	if (devi == NULL) {
		device_delete_child(dev, child);
		return (0);
	}

	/*
	 * NULL all the OFW-related parts of the ivars for non-OFW
	 * children.
	 */
	devi->opd_obdinfo.obd_node = -1;
	devi->opd_obdinfo.obd_name = NULL;
	devi->opd_obdinfo.obd_compat = NULL;
	devi->opd_obdinfo.obd_type = NULL;
	devi->opd_obdinfo.obd_model = NULL;

	device_set_ivars(child, devi);

	return (child);
}
예제 #10
0
파일: zy7_ehci.c 프로젝트: coyizumi/cs111
static int
zy7_ehci_detach(device_t dev)
{
	ehci_softc_t *sc = device_get_softc(dev);

	sc->sc_flags &= ~EHCI_SCFLG_DONEINIT;

	if (device_is_attached(dev))
		bus_generic_detach(dev);

	if (sc->sc_irq_res && sc->sc_intr_hdl)
		/* call ehci_detach() after ehci_init() called after
		 * successful bus_setup_intr().
		 */
		ehci_detach(sc);
	if (sc->sc_bus.bdev) {
		device_detach(sc->sc_bus.bdev);
		device_delete_child(dev, sc->sc_bus.bdev);
	}
	if (sc->sc_irq_res) {
		if (sc->sc_intr_hdl != NULL)
			bus_teardown_intr(dev, sc->sc_irq_res,
					  sc->sc_intr_hdl);
		bus_release_resource(dev, SYS_RES_IRQ,
			     rman_get_rid(sc->sc_irq_res), sc->sc_irq_res);
	}

	if (sc->sc_io_res)
		bus_release_resource(dev, SYS_RES_MEMORY,
			     rman_get_rid(sc->sc_io_res), sc->sc_io_res);
	usb_bus_mem_free_all(&sc->sc_bus, &ehci_iterate_hw_softc);

	return (0);
}
예제 #11
0
/*
 * Since this is not a self-enumerating bus, and since we always add
 * children in attach, we have to always delete children here.
 */
static int
gpiobus_detach(device_t dev)
{
	struct gpiobus_softc *sc;
	struct gpiobus_ivar *devi;
	device_t *devlist;
	int i, err, ndevs;

	sc = GPIOBUS_SOFTC(dev);
	KASSERT(mtx_initialized(&sc->sc_mtx),
	    ("gpiobus mutex not initialized"));
	GPIOBUS_LOCK_DESTROY(sc);

	if ((err = bus_generic_detach(dev)) != 0)
		return (err);

	if ((err = device_get_children(dev, &devlist, &ndevs)) != 0)
		return (err);
	for (i = 0; i < ndevs; i++) {
		device_delete_child(dev, devlist[i]);
		devi = GPIOBUS_IVAR(devlist[i]);
		if (devi->pins) {
			free(devi->pins, M_DEVBUF);
			devi->pins = NULL;
		}
	}
	free(devlist, M_TEMP);

	if (sc->sc_pins_mapped) {
		free(sc->sc_pins_mapped, M_DEVBUF);
		sc->sc_pins_mapped = NULL;
	}

	return (0);
}
예제 #12
0
int
ig4iic_detach(ig4iic_softc_t *sc)
{
	int error;

	if (device_is_attached(sc->dev)) {
		error = bus_generic_detach(sc->dev);
		if (error)
			return (error);
	}
	if (sc->smb)
		device_delete_child(sc->dev, sc->smb);
	if (sc->intr_handle)
		bus_teardown_intr(sc->dev, sc->intr_res, sc->intr_handle);

	sx_xlock(&sc->call_lock);
	mtx_lock(&sc->io_lock);

	sc->smb = NULL;
	sc->intr_handle = NULL;
	reg_write(sc, IG4_REG_INTR_MASK, 0);
	reg_read(sc, IG4_REG_CLR_INTR);
	set_controller(sc, 0);

	mtx_unlock(&sc->io_lock);
	sx_xunlock(&sc->call_lock);
	return (0);
}
예제 #13
0
파일: if_ed.c 프로젝트: ChaosJohn/freebsd
/*
 * Detach the driver from the hardware and other systems in the kernel.
 */
int
ed_detach(device_t dev)
{
	struct ed_softc *sc = device_get_softc(dev);
	struct ifnet *ifp = sc->ifp;

	if (mtx_initialized(ED_MUTEX(sc)))
		ED_ASSERT_UNLOCKED(sc);
	if (ifp) {
		ED_LOCK(sc);
		if (bus_child_present(dev))
			ed_stop(sc);
		ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
		ED_UNLOCK(sc);
		ether_ifdetach(ifp);
		callout_drain(&sc->tick_ch);
	}
	if (sc->irq_res != NULL && sc->irq_handle)
		bus_teardown_intr(dev, sc->irq_res, sc->irq_handle);
	ed_release_resources(dev);
	if (sc->miibus)
		device_delete_child(dev, sc->miibus);
	if (mtx_initialized(ED_MUTEX(sc)))
		ED_LOCK_DESTROY(sc);
	bus_generic_detach(dev);
	return (0);
}
예제 #14
0
static int
ohci_pci_detach(device_t self)
{
	ohci_softc_t *sc = device_get_softc(self);

	if (sc->sc_flags & OHCI_SCFLG_DONEINIT) {
		ohci_detach(sc, 0);
		sc->sc_flags &= ~OHCI_SCFLG_DONEINIT;
	}

	if (sc->irq_res && sc->ih) {
		int err = bus_teardown_intr(self, sc->irq_res, sc->ih);

		if (err)
			/* XXX or should we panic? */
			device_printf(self, "Could not tear down irq, %d\n",
			    err);
		sc->ih = NULL;
	}
	if (sc->sc_bus.bdev) {
		device_delete_child(self, sc->sc_bus.bdev);
		sc->sc_bus.bdev = NULL;
	}
	if (sc->irq_res) {
		bus_release_resource(self, SYS_RES_IRQ, 0, sc->irq_res);
		sc->irq_res = NULL;
	}
	if (sc->io_res) {
		bus_release_resource(self, SYS_RES_MEMORY, PCI_CBMEM, sc->io_res);
		sc->io_res = NULL;
		sc->iot = 0;
		sc->ioh = 0;
	}
	return 0;
}
예제 #15
0
static int
exynos_xhci_detach(device_t dev)
{
	struct exynos_xhci_softc *esc = device_get_softc(dev);
	device_t bdev;
	int err;

	if (esc->base.sc_bus.bdev != NULL) {
		bdev = esc->base.sc_bus.bdev;
		device_detach(bdev);
		device_delete_child(dev, bdev);
	}
	/* During module unload there are lots of children leftover */
	device_delete_children(dev);

	xhci_halt_controller(&esc->base);
	
	if (esc->res[2] && esc->base.sc_intr_hdl) {
		err = bus_teardown_intr(dev, esc->res[2],
		    esc->base.sc_intr_hdl);
		if (err) {
			device_printf(dev, "Could not tear down IRQ,"
			    " %d\n", err);
			return (err);
		}
	}

	bus_release_resources(dev, exynos_xhci_spec, esc->res);

	xhci_uninit(&esc->base);
	
	return (0);
}
예제 #16
0
파일: ig4_iic.c 프로젝트: terimai/ichiic
int
ig4iic_detach(ig4iic_softc_t *sc)
{
	int error;

	mtx_lock(&sc->mtx);

	reg_write(sc, IG4_REG_INTR_MASK, 0);
	reg_read(sc, IG4_REG_CLR_INTR);
	set_controller(sc, 0);

	if (sc->generic_attached) {
		error = bus_generic_detach(sc->dev);
		if (error)
			goto done;
		sc->generic_attached = 0;
	}
	if (sc->smb) {
		device_delete_child(sc->dev, sc->smb);
		sc->smb = NULL;
	}
	if (sc->intr_handle) {
		bus_teardown_intr(sc->dev, sc->intr_res, sc->intr_handle);
		sc->intr_handle = NULL;
	}

	error = 0;
done:
	mtx_unlock(&sc->mtx);
	return error;
}
예제 #17
0
파일: ehci_imx.c 프로젝트: coyizumi/cs111
static int
imx_ehci_detach(device_t dev)
{
	struct imx_ehci_softc *sc;
	ehci_softc_t *esc;

	sc = device_get_softc(dev);

	esc = &sc->ehci_softc;

	if (esc->sc_bus.bdev != NULL)
		device_delete_child(dev, esc->sc_bus.bdev);
	if (esc->sc_flags & EHCI_SCFLG_DONEINIT)
		ehci_detach(esc);
	if (esc->sc_intr_hdl != NULL)
		bus_teardown_intr(dev, esc->sc_irq_res, 
		    esc->sc_intr_hdl);
	if (sc->ehci_irq_res != NULL)
		bus_release_resource(dev, SYS_RES_IRQ, 0, 
		    sc->ehci_irq_res);
	if (sc->ehci_mem_res != NULL)
		bus_release_resource(dev, SYS_RES_MEMORY, 0,
		    sc->ehci_mem_res);

	usb_bus_mem_free_all(&esc->sc_bus, &ehci_iterate_hw_softc);

	/* During module unload there are lots of children leftover */
	device_delete_children(dev);

	return (0);
}
예제 #18
0
파일: fm801.c 프로젝트: kusumi/DragonFlyBSD
static int
fm801_pci_detach(device_t dev)
{
	int r;
	struct fm801_info *fm801;

	DPRINT("Forte Media FM801 detach\n");

	fm801 = pcm_getdevinfo(dev);

	r = bus_generic_detach(dev);
	if (r)
		return r;
	if (fm801->radio != NULL) {
		r = device_delete_child(dev, fm801->radio);
		if (r)
			return r;
		fm801->radio = NULL;
	}

	r = pcm_unregister(dev);
	if (r)
		return r;

	bus_release_resource(dev, fm801->regtype, fm801->regid, fm801->reg);
	bus_teardown_intr(dev, fm801->irq, fm801->ih);
	bus_release_resource(dev, SYS_RES_IRQ, fm801->irqid, fm801->irq);
	bus_dma_tag_destroy(fm801->parent_dmat);
	kfree(fm801, M_DEVBUF);
	return 0;
}
예제 #19
0
static int
a10_ehci_detach(device_t self)
{
	ehci_softc_t *sc = device_get_softc(self);
	device_t bdev;
	int err;
	uint32_t reg_value = 0;

	if (sc->sc_bus.bdev) {
		bdev = sc->sc_bus.bdev;
		device_detach(bdev);
		device_delete_child(self, bdev);
	}
	/* during module unload there are lots of children leftover */
	device_delete_children(self);

	if (sc->sc_irq_res && sc->sc_intr_hdl) {
		/*
		 * only call ehci_detach() after ehci_init()
		 */
		ehci_detach(sc);

		err = bus_teardown_intr(self, sc->sc_irq_res, sc->sc_intr_hdl);

		if (err)
			/* XXX or should we panic? */
			device_printf(self, "Could not tear down irq, %d\n",
			    err);
		sc->sc_intr_hdl = NULL;
	}

	if (sc->sc_irq_res) {
		bus_release_resource(self, SYS_RES_IRQ, 0, sc->sc_irq_res);
		sc->sc_irq_res = NULL;
	}
	if (sc->sc_io_res) {
		bus_release_resource(self, SYS_RES_MEMORY, 0,
		    sc->sc_io_res);
		sc->sc_io_res = NULL;
	}
	usb_bus_mem_free_all(&sc->sc_bus, &ehci_iterate_hw_softc);

	/* Disable configure port */
	reg_value = A10_READ_4(sc, SW_SDRAM_REG_HPCR_USB2);
	reg_value &= ~SW_SDRAM_BP_HPCR_ACCESS;
	A10_WRITE_4(sc, SW_SDRAM_REG_HPCR_USB2, reg_value);

	/* Disable passby */
	reg_value = A10_READ_4(sc, SW_USB_PMU_IRQ_ENABLE);
	reg_value &= ~SW_AHB_INCR8; /* AHB INCR8 disable */
	reg_value &= ~SW_AHB_INCR4; /* AHB burst type INCR4 disable */
	reg_value &= ~SW_AHB_INCRX_ALIGN; /* AHB INCRX align disable */
	reg_value &= ~SW_ULPI_BYPASS; /* ULPI bypass disable */
	A10_WRITE_4(sc, SW_USB_PMU_IRQ_ENABLE, reg_value);

	/* Disable clock for USB */
	a10_clk_usb_deactivate();

	return (0);
}
예제 #20
0
파일: mii.c 프로젝트: AhmadTux/DragonFlyBSD
int
mii_phy_probe(device_t dev, device_t *child, ifm_change_cb_t ifmedia_upd,
	      ifm_stat_cb_t ifmedia_sts)
{
	void			**v;
	int			i;

	v = kmalloc(sizeof(vm_offset_t) * 2, M_DEVBUF, M_INTWAIT);
	v[0] = ifmedia_upd;
	v[1] = ifmedia_sts;
	*child = device_add_child(dev, "miibus", -1);
	device_set_ivars(*child, v);

	for (i = 0; i < MII_NPHY; i++) {
		if (!miibus_no_phy(dev, i))
			break;
	}

	if (i == MII_NPHY) {
		device_delete_child(dev, *child);
		*child = NULL;
		return(ENXIO);
	}

	bus_generic_attach(dev);

	return(0);
}
예제 #21
0
static int
pcf_ebus_detach(device_t dev)
{
	struct pcf_softc *sc;
	int rv;

	sc = DEVTOSOFTC(dev);

	if ((rv = bus_generic_detach(dev)) != 0)
		return (rv);

	if ((rv = device_delete_child(dev, sc->iicbus)) != 0)
		return (rv);

	if (sc->res_irq != 0) {
		bus_teardown_intr(dev, sc->res_irq,
		    sc->intr_cookie);
		bus_release_resource(dev, SYS_RES_IRQ, sc->rid_irq,
		    sc->res_irq);
	}

	bus_release_resource(dev, SYS_RES_MEMORY, sc->rid_ioport,
	    sc->res_ioport);

	return (0);
}
예제 #22
0
파일: twe_freebsd.c 프로젝트: MarginC/kame
/********************************************************************************
 * Bring the controller down to a dormant state and detach all child devices.
 *
 * Note that we can assume that the bioq on the controller is empty, as we won't
 * allow shutdown if any device is open.
 */
static int
twe_shutdown(device_t dev)
{
    struct twe_softc	*sc = device_get_softc(dev);
    int			i, s, error;

    debug_called(4);

    s = splbio();
    error = 0;

    /* 
     * Delete all our child devices.
     */
    for (i = 0; i < TWE_MAX_UNITS; i++) {
	if (sc->twe_drive[i].td_disk != 0) {
	    if ((error = device_delete_child(sc->twe_dev, sc->twe_drive[i].td_disk)) != 0)
		goto out;
	    sc->twe_drive[i].td_disk = 0;
	}
    }

    /*
     * Bring the controller down.
     */
    twe_deinit(sc);

 out:
    splx(s);
    return(error);
}
예제 #23
0
static int
at91_udp_detach(device_t dev)
{
	struct at91_udp_softc *sc = device_get_softc(dev);
	device_t bdev;
	int err;

	if (sc->sc_dci.sc_bus.bdev) {
		bdev = sc->sc_dci.sc_bus.bdev;
		device_detach(bdev);
		device_delete_child(dev, bdev);
	}
	/* during module unload there are lots of children leftover */
	device_delete_children(dev);

	USB_BUS_LOCK(&sc->sc_dci.sc_bus);
	callout_stop(&sc->sc_vbus);
	USB_BUS_UNLOCK(&sc->sc_dci.sc_bus);

	callout_drain(&sc->sc_vbus);

	/* disable Transceiver */
	AT91_UDP_WRITE_4(&sc->sc_dci, AT91_UDP_TXVC, AT91_UDP_TXVC_DIS);

	/* disable and clear all interrupts */
	AT91_UDP_WRITE_4(&sc->sc_dci, AT91_UDP_IDR, 0xFFFFFFFF);
	AT91_UDP_WRITE_4(&sc->sc_dci, AT91_UDP_ICR, 0xFFFFFFFF);

	if (sc->sc_dci.sc_irq_res && sc->sc_dci.sc_intr_hdl) {
		/*
		 * only call at91_udp_uninit() after at91_udp_init()
		 */
		at91dci_uninit(&sc->sc_dci);

		err = bus_teardown_intr(dev, sc->sc_dci.sc_irq_res,
		    sc->sc_dci.sc_intr_hdl);
		sc->sc_dci.sc_intr_hdl = NULL;
	}
	if (sc->sc_dci.sc_irq_res) {
		bus_release_resource(dev, SYS_RES_IRQ, 0,
		    sc->sc_dci.sc_irq_res);
		sc->sc_dci.sc_irq_res = NULL;
	}
	if (sc->sc_dci.sc_io_res) {
		bus_release_resource(dev, SYS_RES_MEMORY, MEM_RID,
		    sc->sc_dci.sc_io_res);
		sc->sc_dci.sc_io_res = NULL;
	}
	usb_bus_mem_free_all(&sc->sc_dci.sc_bus, NULL);

	/* disable clocks */
	at91_pmc_clock_disable(sc->sc_iclk);
	at91_pmc_clock_disable(sc->sc_fclk);
	at91_pmc_clock_disable(sc->sc_mclk);
	at91_pmc_clock_deref(sc->sc_fclk);
	at91_pmc_clock_deref(sc->sc_iclk);
	at91_pmc_clock_deref(sc->sc_mclk);

	return (0);
}
예제 #24
0
/*
 * Called from process context when we discover that a port has
 * been disconnected.
 */
void
usb_disconnect_port(struct usbd_port *up, device_t parent)
{
	usbd_device_handle dev = up->device;
	const char *hubname = device_get_nameunit(parent);
	int i;

	DPRINTFN(3,("uhub_disconnect: up=%p dev=%p port=%d\n",
		    up, dev, up->portno));

#ifdef DIAGNOSTIC
	if (dev == NULL) {
		kprintf("usb_disconnect_port: no device\n");
		return;
	}
#endif

	if (dev->subdevs != NULL) {
		DPRINTFN(3,("usb_disconnect_port: disconnect subdevs\n"));
		for (i = 0; dev->subdevs[i]; i++) {
			kprintf("%s: at %s", device_get_nameunit(dev->subdevs[i]),
			       hubname);
			if (up->portno != 0)
				kprintf(" port %d", up->portno);
			kprintf(" (addr %d) disconnected\n", dev->address);
			device_delete_child(device_get_parent(dev->subdevs[i]), dev->subdevs[i]);
			dev->subdevs[i] = NULL;
		}
	}

	usbd_add_dev_event(USB_EVENT_DEVICE_DETACH, dev);
	dev->bus->devices[dev->address] = NULL;
	up->device = NULL;
	usb_free_device(dev);
}
예제 #25
0
int
ata_pci_detach(device_t dev)
{
    struct ata_pci_controller *ctlr = device_get_softc(dev);
    device_t *children;
    int nchildren, i;

    /* detach & delete all children */
    if (!device_get_children(dev, &children, &nchildren)) {
	for (i = 0; i < nchildren; i++)
	    device_delete_child(dev, children[i]);
	kfree(children, M_TEMP);
    }

    if (ctlr->r_irq) {
	bus_teardown_intr(dev, ctlr->r_irq, ctlr->handle);
	bus_release_resource(dev, SYS_RES_IRQ, ATA_IRQ_RID, ctlr->r_irq);
	ctlr->r_irq = NULL;
    }
    if (ctlr->r_res2) {
	bus_release_resource(dev, ctlr->r_type2, ctlr->r_rid2, ctlr->r_res2);
	ctlr->r_res2 = NULL;
    }
    if (ctlr->r_res1) {
	bus_release_resource(dev, ctlr->r_type1, ctlr->r_rid1, ctlr->r_res1);
	ctlr->r_res1 = NULL;
    }

    return 0;
}
예제 #26
0
static void
at91_add_child(device_t dev, int prio, const char *name, int unit,
    bus_addr_t addr, bus_size_t size, int irq0, int irq1, int irq2)
{
	device_t kid;
	struct at91_ivar *ivar;

	kid = device_add_child_ordered(dev, prio, name, unit);
	if (kid == NULL) {
	    printf("Can't add child %s%d ordered\n", name, unit);
	    return;
	}
	ivar = malloc(sizeof(*ivar), M_DEVBUF, M_NOWAIT | M_ZERO);
	if (ivar == NULL) {
		device_delete_child(dev, kid);
		printf("Can't add alloc ivar\n");
		return;
	}
	device_set_ivars(kid, ivar);
	resource_list_init(&ivar->resources);
	if (irq0 != -1)
		bus_set_resource(kid, SYS_RES_IRQ, 0, irq0, 1);
	if (irq1 != 0)
		bus_set_resource(kid, SYS_RES_IRQ, 1, irq1, 1);
	if (irq2 != 0)
		bus_set_resource(kid, SYS_RES_IRQ, 2, irq2, 1);
	if (addr != 0)
		bus_set_resource(kid, SYS_RES_MEMORY, 0, addr, size);
}
예제 #27
0
/********************************************************************************
 * Bring the controller down to a dormant state and detach all child devices.
 *
 * This function is called before detach, system shutdown, or before performing
 * an operation which may add or delete system disks.  (Call amr_startup to
 * resume normal operation.)
 *
 * Note that we can assume that the bioq on the controller is empty, as we won't
 * allow shutdown if any device is open.
 */
static int
amr_pci_shutdown(device_t dev)
{
    struct amr_softc	*sc = device_get_softc(dev);
    int			i,error;

    debug_called(1);

    /* mark ourselves as in-shutdown */
    sc->amr_state |= AMR_STATE_SHUTDOWN;


    /* flush controller */
    device_printf(sc->amr_dev, "flushing cache...");
    printf("%s\n", amr_flush(sc) ? "failed" : "done");

    error = 0;

    /* delete all our child devices */
    for(i = 0 ; i < AMR_MAXLD; i++) {
	if( sc->amr_drive[i].al_disk != 0) {
	    if((error = device_delete_child(sc->amr_dev,sc->amr_drive[i].al_disk)) != 0)
		goto shutdown_out;
	    sc->amr_drive[i].al_disk = 0;
	}
    }

    /* XXX disable interrupts? */

shutdown_out:
    return(error);
}
예제 #28
0
static int
mv_ehci_detach(device_t self)
{
    ehci_softc_t *sc = device_get_softc(self);
    device_t bdev;
    int err;

    if (sc->sc_bus.bdev) {
        bdev = sc->sc_bus.bdev;
        device_detach(bdev);
        device_delete_child(self, bdev);
    }
    /* during module unload there are lots of children leftover */
    device_delete_children(self);

    /*
     * disable interrupts that might have been switched on in mv_ehci_attach
     */
    if (sc->sc_io_res) {
        EWRITE4(sc, USB_BRIDGE_INTR_MASK, 0);
    }
    if (sc->sc_irq_res && sc->sc_intr_hdl) {
        /*
         * only call ehci_detach() after ehci_init()
         */
        ehci_detach(sc);

        err = bus_teardown_intr(self, sc->sc_irq_res, sc->sc_intr_hdl);

        if (err)
            /* XXX or should we panic? */
            device_printf(self, "Could not tear down irq, %d\n",
                          err);
        sc->sc_intr_hdl = NULL;
    }
    if (irq_err && ih_err) {
        err = bus_teardown_intr(self, irq_err, ih_err);

        if (err)
            device_printf(self, "Could not tear down irq, %d\n",
                          err);
        ih_err = NULL;
    }
    if (irq_err) {
        bus_release_resource(self, SYS_RES_IRQ, 0, irq_err);
        irq_err = NULL;
    }
    if (sc->sc_irq_res) {
        bus_release_resource(self, SYS_RES_IRQ, 1, sc->sc_irq_res);
        sc->sc_irq_res = NULL;
    }
    if (sc->sc_io_res) {
        bus_release_resource(self, SYS_RES_MEMORY, 0,
                             sc->sc_io_res);
        sc->sc_io_res = NULL;
    }
    usb_bus_mem_free_all(&sc->sc_bus, &ehci_iterate_hw_softc);

    return (0);
}
예제 #29
0
파일: mfi_pci.c 프로젝트: JabirTech/Source
static int
mfi_pci_detach(device_t dev)
{
	struct mfi_softc *sc;
	int error, devcount, i;
	device_t *devlist;

	sc = device_get_softc(dev);

	sx_xlock(&sc->mfi_config_lock);
	mtx_lock(&sc->mfi_io_lock);
	if ((sc->mfi_flags & MFI_FLAGS_OPEN) != 0) {
		mtx_unlock(&sc->mfi_io_lock);
		sx_xunlock(&sc->mfi_config_lock);
		return (EBUSY);
	}
	sc->mfi_detaching = 1;
	mtx_unlock(&sc->mfi_io_lock);

	if ((error = device_get_children(sc->mfi_dev, &devlist, &devcount)) != 0) {
		sx_xunlock(&sc->mfi_config_lock);
		return error;
	}
	for (i = 0; i < devcount; i++)
		device_delete_child(sc->mfi_dev, devlist[i]);
	free(devlist, M_TEMP);
	sx_xunlock(&sc->mfi_config_lock);

	EVENTHANDLER_DEREGISTER(shutdown_final, sc->mfi_eh);

	mfi_shutdown(sc);
	mfi_free(sc);
	mfi_pci_free(sc);
	return (0);
}
예제 #30
0
static int
mfi_pci_detach(device_t dev)
{
	struct mfi_softc *sc;
	struct mfi_disk *ld;
	int error;

	sc = device_get_softc(dev);

	sx_xlock(&sc->mfi_config_lock);
	mtx_lock(&sc->mfi_io_lock);
	if ((sc->mfi_flags & MFI_FLAGS_OPEN) != 0) {
		mtx_unlock(&sc->mfi_io_lock);
		sx_xunlock(&sc->mfi_config_lock);
		return (EBUSY);
	}
	sc->mfi_detaching = 1;
	mtx_unlock(&sc->mfi_io_lock);

	while ((ld = TAILQ_FIRST(&sc->mfi_ld_tqh)) != NULL) {
		if ((error = device_delete_child(dev, ld->ld_dev)) != 0) {
			sc->mfi_detaching = 0;
			sx_xunlock(&sc->mfi_config_lock);
			return (error);
		}
	}
	sx_xunlock(&sc->mfi_config_lock);

	EVENTHANDLER_DEREGISTER(shutdown_final, sc->mfi_eh);

	mfi_shutdown(sc);
	mfi_free(sc);
	mfi_pci_free(sc);
	return (0);
}