Beispiel #1
0
/**
 * drm_vblank_off - disable vblank events on a CRTC
 * @dev: DRM device
 * @crtc: CRTC in question
 *
 * Caller must hold event lock.
 */
void drm_vblank_off(struct drm_device *dev, int crtc)
{
	struct drmevlist *list;
	struct drm_pending_event *ev, *tmp;
	struct drm_pending_vblank_event *vev;
	struct timeval now;
	unsigned int seq;

	mtx_enter(&dev->vbl_lock);
	vblank_disable_and_save(dev, crtc);
	wakeup(&dev->vbl_queue[crtc]);

	list = &dev->vbl_events;
	/* Send any queued vblank events, lest the natives grow disquiet */
	seq = drm_vblank_count_and_time(dev, crtc, &now);

	mtx_enter(&dev->event_lock);
	for (ev = TAILQ_FIRST(list); ev != TAILQ_END(list); ev = tmp) {
		tmp = TAILQ_NEXT(ev, link);

		vev = (struct drm_pending_vblank_event *)ev;

		if (vev->pipe != crtc)
			continue;
		DRM_DEBUG("Sending premature vblank event on disable: \
			  wanted %d, current %d\n",
			  vev->event.sequence, seq);
		TAILQ_REMOVE(list, ev, link);
		drm_vblank_put(dev, vev->pipe);
		send_vblank_event(dev, vev, seq, &now);
	}
	mtx_leave(&dev->event_lock);

	mtx_leave(&dev->vbl_lock);
}
Beispiel #2
0
int
midiread(dev_t dev, struct uio *uio, int ioflag)
{
	struct midi_softc *sc;
	struct midi_buffer *mb;
	size_t count;
	int error;

	sc = (struct midi_softc *)device_lookup(&midi_cd, minor(dev));
	if (sc == NULL)
		return ENXIO;
	if (!(sc->flags & FREAD)) {
		error = ENXIO;
		goto done;
	}
	mb = &sc->inbuf;

	/* if there is no data then sleep (unless IO_NDELAY flag is set) */
	error = 0;
	mtx_enter(&audio_lock);
	while (MIDIBUF_ISEMPTY(mb)) {
		if (ioflag & IO_NDELAY) {
			mtx_leave(&audio_lock);
			error = EWOULDBLOCK;
			goto done;
		}
		sc->rchan = 1;
		error = msleep(&sc->rchan, &audio_lock, PWAIT | PCATCH, "mid_rd", 0);
		if (!(sc->dev.dv_flags & DVF_ACTIVE))
			error = EIO;
		if (error) {
			mtx_leave(&audio_lock);
			goto done;
		}
	}

	/* at this stage, there is at least 1 byte */

	while (uio->uio_resid > 0 && mb->used > 0) {
		count = MIDIBUF_SIZE - mb->start;
		if (count > mb->used)
			count = mb->used;
		if (count > uio->uio_resid)
			count = uio->uio_resid;
		mtx_leave(&audio_lock);
		error = uiomove(mb->data + mb->start, count, uio);
		if (error)
			goto done;
		mtx_enter(&audio_lock);
		MIDIBUF_REMOVE(mb, count);
	}
	mtx_leave(&audio_lock);
done:
	device_unref(&sc->dev);
	return error;
}
Beispiel #3
0
void
vdsp_read(void *arg1)
{
	struct vdsp_softc *sc = arg1;

	mtx_enter(&sc->sc_desc_mtx);
	while (sc->sc_desc_tail != sc->sc_desc_head) {
		mtx_leave(&sc->sc_desc_mtx);
		vdsp_read_desc(sc, sc->sc_desc_msg[sc->sc_desc_tail]);
		mtx_enter(&sc->sc_desc_mtx);
		sc->sc_desc_tail++;
		sc->sc_desc_tail &= (VDSK_RX_ENTRIES - 1);
	}
	mtx_leave(&sc->sc_desc_mtx);
}
Beispiel #4
0
int
yds_halt_output(void *addr)
{
	struct yds_softc *sc = addr;

	DPRINTF(("yds: yds_halt_output\n"));
	mtx_enter(&audio_lock);
	if (sc->sc_play.intr) {
		sc->sc_play.intr = 0;
		/* Sync play slot control data */
		bus_dmamap_sync(sc->sc_dmatag, sc->sc_ctrldata.map,
				sc->pbankoff,
				sizeof(struct play_slot_ctrl_bank)*
				    (*sc->ptbl)*N_PLAY_SLOT_CTRL_BANK,
				BUS_DMASYNC_POSTWRITE|BUS_DMASYNC_POSTREAD);
		/* Stop the play slot operation */
		sc->pbankp[0]->status =
		sc->pbankp[1]->status =
		sc->pbankp[2]->status =
		sc->pbankp[3]->status = 1;
		/* Sync ring buffer */
		bus_dmamap_sync(sc->sc_dmatag, sc->sc_play.dma->map,
				0, sc->sc_play.length, BUS_DMASYNC_POSTWRITE);
	}
	mtx_leave(&audio_lock);
	return 0;
}
Beispiel #5
0
void
drm_handle_vblank_events(struct drm_device *dev, int crtc)
{
	struct drmevlist		*list;
	struct drm_pending_event	*ev, *tmp;
	struct drm_pending_vblank_event	*vev;
	struct timeval			 now;
	u_int				 seq;

	list = &dev->vblank->vb_crtcs[crtc].vbl_events;
	microtime(&now);
	seq = drm_vblank_count(dev, crtc);

	mtx_enter(&dev->event_lock);
	for (ev = TAILQ_FIRST(list); ev != TAILQ_END(list); ev = tmp) {
		tmp = TAILQ_NEXT(ev, link);

		vev = (struct drm_pending_vblank_event *)ev;

		if ((seq - vev->event.sequence) > (1 << 23))
			continue;
		DPRINTF("%s: got vblank event on crtc %d, value %d\n",
		    __func__, crtc, seq);
		
		vev->event.sequence = seq;
		vev->event.tv_sec = now.tv_sec;
		vev->event.tv_usec = now.tv_usec;
		drm_vblank_put(dev, crtc);
		TAILQ_REMOVE(list, ev, link);
		TAILQ_INSERT_TAIL(&ev->file_priv->evlist, ev, link);
		wakeup(&ev->file_priv->evlist);
		selwakeup(&ev->file_priv->rsel);
	}
	mtx_leave(&dev->event_lock);
}
Beispiel #6
0
Datei: umidi.c Projekt: bluhm/sys
static void
out_intr(struct usbd_xfer *xfer, void *priv, usbd_status status)
{
	struct umidi_endpoint *ep = (struct umidi_endpoint *)priv;
	struct umidi_softc *sc = ep->sc;
	struct umidi_jack *j;
	unsigned pending;
	
	if (usbd_is_dying(sc->sc_udev))
		return;

	ep->used = 0;
	ep->busy = 0;
	for (pending = ep->pending; pending > 0; pending--) {
		j = SIMPLEQ_FIRST(&ep->intrq);
#ifdef DIAGNOSTIC
		if (j == NULL) {
			printf("umidi: missing intr entry\n");
			break;
		}
#endif
		SIMPLEQ_REMOVE_HEAD(&ep->intrq, intrq_entry);
		ep->pending--;
		j->intr = 0;
		mtx_enter(&audio_lock);
		if (j->opened && j->u.out.intr)
			(*j->u.out.intr)(j->arg);
		mtx_leave(&audio_lock);
	}
}
Beispiel #7
0
void
taskq_destroy(struct taskq *tq)
{
    mtx_enter(&tq->tq_mtx);
    switch (tq->tq_state) {
    case TQ_S_CREATED:
        /* tq is still referenced by taskq_create_thread */
        tq->tq_state = TQ_S_DESTROYED;
        mtx_leave(&tq->tq_mtx);
        return;

    case TQ_S_RUNNING:
        tq->tq_state = TQ_S_DESTROYED;
        break;

    default:
        panic("unexpected %s tq state %u", tq->tq_name, tq->tq_state);
    }

    while (tq->tq_running > 0) {
        wakeup(tq);
        msleep(&tq->tq_running, &tq->tq_mtx, PWAIT, "tqdestroy", 0);
    }
    mtx_leave(&tq->tq_mtx);

    free(tq, M_DEVBUF, sizeof(*tq));
}
Beispiel #8
0
void ttm_read_unlock(struct ttm_lock *lock)
{
	mtx_enter(&lock->lock);
	if (--lock->rw == 0)
		wakeup(&lock->queue);
	mtx_leave(&lock->lock);
}
Beispiel #9
0
void ttm_write_lock_downgrade(struct ttm_lock *lock)
{
	mtx_enter(&lock->lock);
	lock->rw = 1;
	wakeup(&lock->queue);
	mtx_leave(&lock->lock);
}
Beispiel #10
0
void
smp_rendezvous_cpus(unsigned long map,
	void (* action_func)(void *),
	void *arg)
{
	unsigned int cpumask = 1 << cpu_number();

	if (ncpus == 1) {
		if (action_func != NULL)
			action_func(arg);
		return;
	}

	/* obtain rendezvous lock */
        mtx_enter(&smp_ipi_mtx);

	/* set static function pointers */
	smp_rv_map = map;
	smp_rv_action_func = action_func;
	smp_rv_func_arg = arg;
	smp_rv_waiters[0] = 0;
	smp_rv_waiters[1] = 0;

	/* signal other processors, which will enter the IPI with interrupts off */
	mips64_multicast_ipi(map & ~cpumask, MIPS64_IPI_RENDEZVOUS);

	/* Check if the current CPU is in the map */
	if (map & cpumask)
		smp_rendezvous_action();

	while (smp_rv_waiters[1] != smp_rv_map)
		;
	/* release lock */
	mtx_leave(&smp_ipi_mtx);
}
Beispiel #11
0
int
drm_vblank_get(struct drm_device *dev, int crtc)
{
	struct drm_vblank_info	*vbl = dev->vblank;
	int			 ret = 0;

	if (dev->irq_enabled == 0)
		return (EINVAL);

	mtx_enter(&vbl->vb_lock);
	DPRINTF("%s: %d refs = %d\n", __func__, crtc,
	    vbl->vb_crtcs[crtc].vbl_refs);
	vbl->vb_crtcs[crtc].vbl_refs++;
	if (vbl->vb_crtcs[crtc].vbl_refs == 1 &&
	    vbl->vb_crtcs[crtc].vbl_enabled == 0) {
		if ((ret = dev->driver->enable_vblank(dev, crtc)) == 0) {
			vbl->vb_crtcs[crtc].vbl_enabled = 1;
			drm_update_vblank_count(dev, crtc);
		} else {
			vbl->vb_crtcs[crtc].vbl_refs--;
		}

	}
	mtx_leave(&vbl->vb_lock);

	return (ret);
}
Beispiel #12
0
int
yds_halt_input(void *addr)
{
	struct yds_softc *sc = addr;

	DPRINTF(("yds: yds_halt_input\n"));
	mtx_enter(&audio_lock);
	if (sc->sc_rec.intr) {
		/* Stop the rec slot operation */
		YWRITE4(sc, YDS_MAPOF_REC, 0);
		sc->sc_rec.intr = 0;
		/* Sync rec slot control data */
		bus_dmamap_sync(sc->sc_dmatag, sc->sc_ctrldata.map,
				sc->rbankoff,
				sizeof(struct rec_slot_ctrl_bank)*
				    N_REC_SLOT_CTRL*N_REC_SLOT_CTRL_BANK,
				BUS_DMASYNC_POSTWRITE|BUS_DMASYNC_POSTREAD);
		/* Sync ring buffer */
		bus_dmamap_sync(sc->sc_dmatag, sc->sc_rec.dma->map,
				0, sc->sc_rec.length, BUS_DMASYNC_POSTREAD);
	}
	sc->sc_rec.intr = NULL;
	mtx_leave(&audio_lock);
	return 0;
}
Beispiel #13
0
int
neo_trigger_output(void *addr, void *start, void *end, int blksize,
    void (*intr)(void *), void *arg, struct audio_params *param)
{
	struct neo_softc *sc = addr;
	int ssz;

	mtx_enter(&audio_lock);
	sc->pintr = intr;
	sc->parg = arg;

	ssz = (param->precision * param->factor == 16)? 2 : 1;
	if (param->channels == 2)
		ssz <<= 1;

	sc->pbufsize = ((char *)end - (char *)start);
	sc->pblksize = blksize;
	sc->pwmark = blksize;
	nm_wr(sc, NM_PBUFFER_START, sc->pbuf, 4);
	nm_wr(sc, NM_PBUFFER_END, sc->pbuf + sc->pbufsize - ssz, 4);
	nm_wr(sc, NM_PBUFFER_CURRP, sc->pbuf, 4);
	nm_wr(sc, NM_PBUFFER_WMARK, sc->pbuf + sc->pwmark, 4);
	nm_wr(sc, NM_PLAYBACK_ENABLE_REG, NM_PLAYBACK_FREERUN |
	    NM_PLAYBACK_ENABLE_FLAG, 1);
	nm_wr(sc, NM_AUDIO_MUTE_REG, 0, 2);
	mtx_leave(&audio_lock);
	return (0);
}
Beispiel #14
0
int
fms_trigger_input(void *addr, void *start, void *end, int blksize,
    void (*intr)(void *), void *arg, struct audio_params *param)
{
	struct fms_softc *sc = addr;
	struct fms_dma *p;
	
	sc->sc_rintr = intr;
	sc->sc_rarg = arg;
	
	for (p = sc->sc_dmas; p && p->addr != start; p = p->next)
		;
	
	if (!p)
		panic("fms_trigger_input: request with bad start "
		      "address (%p)", start);

	sc->sc_rec_start = p->map->dm_segs[0].ds_addr;
	sc->sc_rec_end = sc->sc_rec_start + ((char *)end - (char *)start);
	sc->sc_rec_blksize = blksize;
	sc->sc_rec_nextblk = sc->sc_rec_start + sc->sc_rec_blksize;	
	sc->sc_rec_flip = 0;
	mtx_enter(&audio_lock);
	bus_space_write_2(sc->sc_iot, sc->sc_ioh, FM_REC_DMALEN, blksize - 1);
	bus_space_write_4(sc->sc_iot, sc->sc_ioh, FM_REC_DMABUF1, 
			  sc->sc_rec_start);
	bus_space_write_4(sc->sc_iot, sc->sc_ioh, FM_REC_DMABUF2, 
			  sc->sc_rec_nextblk);
	bus_space_write_2(sc->sc_iot, sc->sc_ioh, FM_REC_CTL, 
			  FM_REC_START | FM_REC_STOPNOW | sc->sc_rec_reg);
	mtx_leave(&audio_lock);
	return 0;
}
Beispiel #15
0
/*
 * softintr_dispatch:
 *
 *	Process pending software interrupts.
 */
void
softintr_dispatch(int which)
{
	struct i386_soft_intr *si = &i386_soft_intrs[which];
	struct i386_soft_intrhand *sih;

	KERNEL_LOCK();
	for (;;) {
		mtx_enter(&si->softintr_lock);
		sih = TAILQ_FIRST(&si->softintr_q);
		if (sih == NULL) {
			mtx_leave(&si->softintr_lock);
			break;
		}
		TAILQ_REMOVE(&si->softintr_q, sih, sih_q);
		sih->sih_pending = 0;

		uvmexp.softs++;

		mtx_leave(&si->softintr_lock);

		(*sih->sih_fn)(sih->sih_arg);
	}
	KERNEL_UNLOCK();
}
Beispiel #16
0
int
ad1848_trigger_input(void *addr, void *start, void *end, int blksize,
                     void (*intr)(void *), void *arg, struct audio_params *param)
{
    struct ad1848_softc *sc = addr;
    u_char reg;

    if (sc->sc_recdrq == -1) {
        DPRINTF(("ad1848_trigger_input: invalid recording drq\n"));
        return ENXIO;
    }
    mtx_enter(&audio_lock);
    isa_dmastart(sc->sc_isa, sc->sc_recdrq, start,
                 (char *)end - (char *)start, NULL, DMAMODE_READ | DMAMODE_LOOP,
                 BUS_DMA_NOWAIT);

    sc->sc_recrun = 1;
    sc->sc_rintr = intr;
    sc->sc_rarg = arg;

    blksize = (blksize * NBBY) / (param->precision * param->channels) - 1;

    if (sc->mode == 2) {
        ad_write(sc, CS_LOWER_REC_CNT, (blksize & 0xff));
        ad_write(sc, CS_UPPER_REC_CNT, ((blksize >> 8) & 0xff));
    } else {
Beispiel #17
0
/*
 * Endless loop.  We grab pages in increments of 16 pages, then
 * quickly swap them into the list.  At some point we can consider
 * returning memory to the system if we have too many free pages,
 * but that's not implemented yet.
 */
void
uvm_km_thread(void *arg)
{
	struct km_page *head, *tail, *page;
	int i, want;

	for (i = want = 16; ; ) {
		if (i < want || uvm_km_pages_free >= uvm_km_pages_lowat)
			tsleep(&uvm_km_pages_head, PVM, "kmalloc", 0);
		for (i = 0; i < want; i++) {
			page = (struct km_page *)uvm_km_kmemalloc(kernel_map,
			    NULL, PAGE_SIZE, 0);
			if (i == 0)
				head = tail = page;
			if (page == NULL)
				break;
			page->next = head;
			head = page;
		}
		if (head != NULL) {
			mtx_enter(&uvm_km_mtx);
			tail->next = uvm_km_pages_head;
			uvm_km_pages_head = head;
			uvm_km_pages_free += i;
			mtx_leave(&uvm_km_mtx);
		}
		if (uvm_km_pages_free)
			wakeup(&uvm_km_pages_free);
	}
}
Beispiel #18
0
/*
 * softintr_dispatch:
 *
 *	Process pending software interrupts.
 */
void
softintr_dispatch(int which)
{
	struct i386_soft_intr		*si = &i386_soft_intrs[which];
	struct i386_soft_intrhand	*sih;
	void				*arg;
	void				(*fn)(void *);

	for (;;) {
		mtx_enter(&si->softintr_lock);
		sih = TAILQ_FIRST(&si->softintr_q);
		if (sih == NULL) {
			mtx_leave(&si->softintr_lock);
			break;
		}
		TAILQ_REMOVE(&si->softintr_q, sih, sih_q);
		sih->sih_pending = 0;

		uvmexp.softs++;
		arg = sih->sih_arg;
		fn = sih->sih_fn;

		mtx_leave(&si->softintr_lock);
		(*fn)(arg);
	}
}
Beispiel #19
0
Datei: neo.c Projekt: bluhm/sys
int
neo_trigger_input(void *addr, void *start, void *end, int blksize,
    void (*intr)(void *), void *arg, struct audio_params *param)
{
	struct neo_softc *sc = addr;
	int ssz;

	mtx_enter(&audio_lock);
	sc->rintr = intr;
	sc->rarg = arg;

	ssz = (param->precision == 16) ? 2 : 1;
	if (param->channels == 2)
		ssz <<= 1;

	sc->rbufsize = ((char *)end - (char *)start);
	sc->rblksize = blksize;
	sc->rwmark = blksize;
	nm_wr(sc, NM_RBUFFER_START, sc->rbuf, 4);
	nm_wr(sc, NM_RBUFFER_END, sc->rbuf + sc->rbufsize, 4);
	nm_wr(sc, NM_RBUFFER_CURRP, sc->rbuf, 4);
	nm_wr(sc, NM_RBUFFER_WMARK, sc->rbuf + sc->rwmark, 4);
	nm_wr(sc, NM_RECORD_ENABLE_REG, NM_RECORD_FREERUN |
	    NM_RECORD_ENABLE_FLAG, 1);
	mtx_leave(&audio_lock);
	return (0);
}
Beispiel #20
0
/**
 * Uninstall the IRQ handler.
 *
 * \param dev DRM device.
 *
 * Calls the driver's \c irq_uninstall() function, and stops the irq.
 */
int drm_irq_uninstall(struct drm_device *dev)
{
	int i;

	DRM_LOCK();
	if (!dev->irq_enabled) {
		DRM_UNLOCK();
		return (EINVAL);
	}

	dev->irq_enabled = 0;
	DRM_UNLOCK();

	/*
	 * Ick. we're about to turn of vblanks, so make sure anyone waiting
	 * on them gets woken up. Also make sure we update state correctly
	 * so that we can continue refcounting correctly.
	 */
	if (dev->num_crtcs) {
		mtx_enter(&dev->vbl_lock);
		for (i = 0; i < dev->num_crtcs; i++) {
			wakeup(&dev->vbl_queue[i]);
			dev->vblank_enabled[i] = 0;
			dev->last_vblank[i] =
			    dev->driver->get_vblank_counter(dev, i);
		}
		mtx_leave(&dev->vbl_lock);
	}

	DRM_DEBUG("irq=%d\n", dev->irq);

	dev->driver->irq_uninstall(dev);

	return (0);
}
Beispiel #21
0
void
mvmdio_miibus_writereg(struct device *dev, int phy, int reg, int val)
{
	struct mvmdio_softc *sc = (struct mvmdio_softc *) dev;
	uint32_t smi;
	int i;

	mtx_enter(&sc->sc_mtx);

	for (i = 0; i < MVNETA_PHY_TIMEOUT; i++) {
		DELAY(1);
		if (!(MVNETA_READ(sc, 0) & MVNETA_SMI_BUSY))
			break;
	}
	if (i == MVNETA_PHY_TIMEOUT) {
		printf("%s: SMI busy timeout\n", sc->sc_dev.dv_xname);
		mtx_leave(&sc->sc_mtx);
		return;
	}

	smi = MVNETA_SMI_PHYAD(phy) | MVNETA_SMI_REGAD(reg) |
	    MVNETA_SMI_OPCODE_WRITE | (val & MVNETA_SMI_DATA_MASK);
	MVNETA_WRITE(sc, 0, smi);

	for (i = 0; i < MVNETA_PHY_TIMEOUT; i++) {
		DELAY(1);
		if (!(MVNETA_READ(sc, 0) & MVNETA_SMI_BUSY))
			break;
	}

	mtx_leave(&sc->sc_mtx);

	if (i == MVNETA_PHY_TIMEOUT)
		printf("%s: phy write timed out\n", sc->sc_dev.dv_xname);
}
Beispiel #22
0
void
midi_timeout(void *addr)
{
	mtx_enter(&audio_lock);
	midi_ointr(addr);
	mtx_leave(&audio_lock);
}
Beispiel #23
0
void ttm_write_unlock(struct ttm_lock *lock)
{
	mtx_enter(&lock->lock);
	lock->rw = 0;
	wakeup(&lock->queue);
	mtx_leave(&lock->lock);
}
Beispiel #24
0
int
midipoll(dev_t dev, int events, struct proc *p)
{
	struct midi_softc *sc;
	int revents;

	sc = (struct midi_softc *)device_lookup(&midi_cd, minor(dev));
	if (sc == NULL)
		return POLLERR;
	revents = 0;
	mtx_enter(&audio_lock);
	if (events & (POLLIN | POLLRDNORM)) {
		if (!MIDIBUF_ISEMPTY(&sc->inbuf))
			revents |= events & (POLLIN | POLLRDNORM);
	}
	if (events & (POLLOUT | POLLWRNORM)) {
		if (!MIDIBUF_ISFULL(&sc->outbuf))
			revents |= events & (POLLOUT | POLLWRNORM);
	}
	if (revents == 0) {
		if (events & (POLLIN | POLLRDNORM))
			selrecord(p, &sc->rsel);
		if (events & (POLLOUT | POLLWRNORM))
			selrecord(p, &sc->wsel);
	}
	mtx_leave(&audio_lock);
	device_unref(&sc->dev);
	return (revents);
}
Beispiel #25
0
void ttm_suspend_unlock(struct ttm_lock *lock)
{
	mtx_enter(&lock->lock);
	lock->flags &= ~TTM_SUSPEND_LOCK;
	wakeup(&lock->queue);
	mtx_leave(&lock->lock);
}
Beispiel #26
0
int
midikqfilter(dev_t dev, struct knote *kn)
{
	struct midi_softc *sc;
	struct klist 	  *klist;
	int error;

	sc = (struct midi_softc *)device_lookup(&midi_cd, minor(dev));
	if (sc == NULL)
		return ENXIO;
	error = 0;
	switch (kn->kn_filter) {
	case EVFILT_READ:
		klist = &sc->rsel.si_note;
		kn->kn_fop = &midiread_filtops;
		break;
	case EVFILT_WRITE:
		klist = &sc->wsel.si_note;
		kn->kn_fop = &midiwrite_filtops;
		break;
	default:
		error = EINVAL;
		goto done;
	}
	kn->kn_hook = (void *)sc;

	mtx_enter(&audio_lock);
	SLIST_INSERT_HEAD(klist, kn, kn_selnext);
	mtx_leave(&audio_lock);
done:
	device_unref(&sc->dev);
	return error;
}
Beispiel #27
0
struct mbuf *
m_free(struct mbuf *m)
{
	struct mbuf *n;

	if (m == NULL)
		return (NULL);

	mtx_enter(&mbstatmtx);
	mbstat.m_mtypes[m->m_type]--;
	mtx_leave(&mbstatmtx);

	n = m->m_next;
	if (m->m_flags & M_ZEROIZE) {
		m_zero(m);
		/* propagate M_ZEROIZE to the next mbuf in the chain */
		if (n)
			n->m_flags |= M_ZEROIZE;
	}
	if (m->m_flags & M_PKTHDR)
		m_tag_delete_chain(m);
	if (m->m_flags & M_EXT)
		m_extfree(m);

	pool_put(&mbpool, m);

	return (n);
}
Beispiel #28
0
void
buf_free_pages(struct buf *bp)
{
	struct uvm_object *uobj = bp->b_pobj;
	struct vm_page *pg;
	voff_t off, i;
	int s;

	KASSERT(bp->b_data == NULL);
	KASSERT(uobj != NULL);

	s = splbio();

	off = bp->b_poffs;
	bp->b_pobj = NULL;
	bp->b_poffs = 0;

	mtx_enter(&uobj->vmobjlock);
	for (i = 0; i < atop(bp->b_bufsize); i++) {
		pg = uvm_pagelookup(uobj, off + ptoa(i));
		KASSERT(pg != NULL);
		KASSERT(pg->wire_count == 1);
		pg->wire_count = 0;
		/* Never on a pageq, no pageqlock needed.  */
		uvm_pagefree(pg);
		bcstats.numbufpages--;
	}
	mtx_leave(&uobj->vmobjlock);
	splx(s);
}
Beispiel #29
0
int
taskq_next_work(struct taskq *tq, struct task *work, sleepfn tqsleep)
{
    struct task *next;

    mtx_enter(&tq->tq_mtx);
    while ((next = TAILQ_FIRST(&tq->tq_worklist)) == NULL) {
        if (tq->tq_state != TQ_S_RUNNING) {
            mtx_leave(&tq->tq_mtx);
            return (0);
        }

        tqsleep(tq, &tq->tq_mtx, PWAIT, "bored", 0);
    }

    TAILQ_REMOVE(&tq->tq_worklist, next, t_entry);
    CLR(next->t_flags, TASK_ONQUEUE);

    *work = *next; /* copy to caller to avoid races */

    next = TAILQ_FIRST(&tq->tq_worklist);
    mtx_leave(&tq->tq_mtx);

    if (next != NULL)
        wakeup_one(tq);

    return (1);
}
Beispiel #30
0
Datei: umidi.c Projekt: bluhm/sys
static void
in_intr(struct usbd_xfer *xfer, void *priv, usbd_status status)
{
	int cn, evlen, remain, i;
	unsigned char *buf;
	struct umidi_endpoint *ep = (struct umidi_endpoint *)priv;
	struct umidi_jack *jack;

	if (usbd_is_dying(ep->sc->sc_udev))
		return;

	usbd_get_xfer_status(xfer, NULL, NULL, &remain, NULL);
	if (status != USBD_NORMAL_COMPLETION) {
		DPRINTF(("%s: abnormal status: %s\n", __func__, usbd_errstr(status)));
		return;
	}
	buf = ep->buffer;
	while (remain >= UMIDI_PACKET_SIZE) {
		cn = GET_CN(buf[0]);
		if (cn < ep->num_jacks && (jack = ep->jacks[cn]) &&
		    jack->binded && jack->opened &&  jack->u.in.intr) {
		    	evlen = packet_length[GET_CIN(buf[0])];
			mtx_enter(&audio_lock);
			for (i=0; i<evlen; i++)
				(*jack->u.in.intr)(jack->arg, buf[i+1]);
			mtx_leave(&audio_lock);
		}
		buf += UMIDI_PACKET_SIZE;
		remain -= UMIDI_PACKET_SIZE;
	}
	(void)start_input_transfer(ep);
}