static int
sbmem_rw(dev_t dev, struct uio *uio, enum uio_rw rw, cred_t *cred)
{
	uint_t c;
	struct iovec *iov;
	struct sbusmem_unit *un;
	uint_t pagesize, msize;
	int instance, error = 0;
	dev_info_t *dip;
	caddr_t reg;

#if defined(lint) || defined(__lint)
	cred = cred;
#endif /* lint || __lint */

	instance = getminor(dev);
	if ((un = ddi_get_soft_state(sbusmem_state_head, instance)) == NULL) {
		return (ENXIO);
	}
	dip = un->dip;
	pagesize = un->pagesize;

	while (uio->uio_resid > 0 && error == 0) {
		iov = uio->uio_iov;
		if (iov->iov_len == 0) {
			uio->uio_iov++;
			uio->uio_iovcnt--;
			if (uio->uio_iovcnt < 0)
				cmn_err(CE_PANIC, "sbmem_rw");
			continue;
		}

		if (uio->uio_offset > un->size) {
			return (EFAULT);
		}

		if (uio->uio_offset == un->size) {
			return (0);		/* EOF */
		}
		msize = pagesize - (uio->uio_offset & (pagesize - 1));
		if (ddi_map_regs(dip, 0, &reg, uio->uio_offset,
		    (off_t)msize) != DDI_SUCCESS) {
			return (EFAULT);
		}
		c = min(msize, (uint_t)iov->iov_len);
		if (ddi_peekpokeio(dip, uio, rw, reg, (int)c,
		    sizeof (int)) != DDI_SUCCESS)
			error = EFAULT;

		ddi_unmap_regs(dip, 0, &reg, uio->uio_offset, (off_t)msize);
	}
	return (error);
}
Exemple #2
0
/* ARGSUSED */
static int
simmstat_detach(dev_info_t *devi, ddi_detach_cmd_t cmd)
{
    int instance;
    struct simmstat_soft_state *softsp;

    /* get the instance of this devi */
    instance = ddi_get_instance(devi);

    /* get the soft state pointer for this device node */
    softsp = ddi_get_soft_state(simmstatp, instance);

    switch (cmd) {
    case DDI_SUSPEND:
        return (DDI_SUCCESS);

    case DDI_DETACH:
        (void) fhc_bdlist_lock(softsp->board);
        if (fhc_bd_detachable(softsp->board))
            break;
        else
            fhc_bdlist_unlock();
    /* FALLTHROUGH */

    default:
        return (DDI_FAILURE);
    }

    fhc_bdlist_unlock();

    /* remove the kstat for this board */
    kstat_delete(softsp->simmstat_ksp);

    /* unmap the registers */
    ddi_unmap_regs(softsp->dip, 0,
                   (caddr_t *)&softsp->simmstat_base, 0, 0);

    /* free up the soft state */
    ddi_soft_state_free(simmstatp, instance);
    ddi_prop_remove_all(devi);

    return (DDI_SUCCESS);
}
/*ARGSUSED*/
static int
dmadetach(dev_info_t *devi, ddi_detach_cmd_t cmd)
{
	dma_softc_t *dp, *pdp = NULL;

	switch (cmd) {
	case DDI_SUSPEND:
		return (DDI_SUCCESS);

	case DDI_DETACH:
		mutex_enter(&dmaautolock);
		for (dp = dma_softc; dp; pdp = dp, dp = dp->dma_next) {
			if (dp->dma_dev == devi)
				break;
		}
		ASSERT(dp != NULL);
		if (dp->dma_use) {
			mutex_exit(&dmaautolock);
			return (DDI_FAILURE);
		}
		if (dma_softc == dp) {
			dma_softc = dp->dma_next;
		} else if (dp->dma_next == NULL) {
			pdp->dma_next = NULL;
		} else {
			pdp->dma_next = dp->dma_next;
		}
		mutex_exit(&dmaautolock);
		ddi_unmap_regs(devi, 0, (caddr_t *)(&dp->dma_regs), 0, 0);
		kmem_free(dp, sizeof (dma_softc_t));
		return (DDI_SUCCESS);

	default:
		return (DDI_FAILURE);
	}
}