示例#1
0
文件: usbf.c 项目: sofuture/bitrig
/*
 * Process context for USB function tasks.
 */
void
usbf_task_thread(void *arg)
{
	struct usbf_softc *sc = arg;
	struct usbf_task *task;
	int s;

	DPRINTF(0,("usbf_task_thread: start (pid %d)\n", curproc->p_pid));

	s = splusb();
	while (!sc->sc_dying) {
		task = TAILQ_FIRST(&sc->sc_tskq);
		if (task == NULL) {
			tsleep(&sc->sc_tskq, PWAIT, "usbtsk", 0);
			task = TAILQ_FIRST(&sc->sc_tskq);
		}
		DPRINTF(1,("usbf_task_thread: woke up task=%p\n", task));
		if (task != NULL) {
			TAILQ_REMOVE(&sc->sc_tskq, task, next);
			task->onqueue = 0;
			splx(s);
			task->fun(task->arg);
			s = splusb();
			DPRINTF(1,("usbf_task_thread: done task=%p\n", task));
		}
	}
	splx(s);

	DPRINTF(0,("usbf_task_thread: exit\n"));
	kthread_exit(0);
}
示例#2
0
usbd_status
usb_allocmem(usbd_bus_handle bus, size_t size, size_t align, usb_dma_t *p)
{
	bus_dma_tag_t tag = bus->parent_dmatag;
	usbd_status err;
	struct usb_frag_dma *f;
	usb_dma_block_t *b;
	int i;
	int s;

	/* compat w/ Net/OpenBSD */
	if (align == 0)
		align = 1;

	/* If the request is large then just use a full block. */
	if (size > USB_MEM_SMALL || align > USB_MEM_SMALL) {
		DPRINTFN(1, ("usb_allocmem: large alloc %d\n", (int)size));
		size = (size + USB_MEM_BLOCK - 1) & ~(USB_MEM_BLOCK - 1);
		err = usb_block_allocmem(tag, size, align, &p->block);
		if (!err) {
			p->block->fullblock = 1;
			p->offs = 0;
			p->len = size;
		}
		return (err);
	}

	s = splusb();
	/* Check for free fragments. */
	for (f = LIST_FIRST(&usb_frag_freelist); f; f = LIST_NEXT(f, next))
		if (f->block->tag == tag)
			break;
	if (f == NULL) {
		DPRINTFN(1, ("usb_allocmem: adding fragments\n"));
		err = usb_block_allocmem(tag, USB_MEM_BLOCK, USB_MEM_SMALL,&b);
		if (err) {
			splx(s);
			return (err);
		}
		b->fullblock = 0;
		/* XXX - override the tag, ok since we never free it */
		b->tag = tag;
		KASSERT(sizeof *f <= USB_MEM_SMALL, ("USB_MEM_SMALL(%d) is too small for struct usb_frag_dma(%zd)\n",
		    USB_MEM_SMALL, sizeof *f));
		for (i = 0; i < USB_MEM_BLOCK; i += USB_MEM_SMALL) {
			f = (struct usb_frag_dma *)((char *)b->kaddr + i);
			f->block = b;
			f->offs = i;
			LIST_INSERT_HEAD(&usb_frag_freelist, f, next);
		}
		f = LIST_FIRST(&usb_frag_freelist);
	}
	p->block = f->block;
	p->offs = f->offs;
	p->len = USB_MEM_SMALL;
	LIST_REMOVE(f, next);
	splx(s);
	DPRINTFN(5, ("usb_allocmem: use frag=%p size=%d\n", f, (int)size));
	return (USBD_NORMAL_COMPLETION);
}
示例#3
0
文件: umidi.c 项目: bluhm/sys
static int
out_jack_output(struct umidi_jack *j, int d)
{
	struct umidi_endpoint *ep = j->endpoint;
	struct umidi_softc *sc = ep->sc;
	int s;

	if (usbd_is_dying(sc->sc_udev))
		return 1;
	if (!j->opened)
		return 1;
	s = splusb();
	if (ep->busy) {
		if (!j->intr) {
			SIMPLEQ_INSERT_TAIL(&ep->intrq, j, intrq_entry);
			ep->pending++;
			j->intr = 1;
		}		
		splx(s);
		return 0;
	}
	if (!out_build_packet(j->cable_number, &j->packet, d,
		ep->buffer + ep->used)) {
		splx(s);
		return 1;
	}
	ep->used += UMIDI_PACKET_SIZE;
	if (ep->used == ep->packetsize) {
		ep->busy = 1;
		start_output_transfer(ep);
	}
	splx(s);
	return 1;
}
int
uirda_poll(void *h, int events, struct lwp *l)
{
	struct uirda_softc *sc = h;
	int revents = 0;
	int s;

	DPRINTFN(1,("%s: sc=%p\n", __func__, sc));

	s = splusb();
	if (events & (POLLOUT | POLLWRNORM))
		revents |= events & (POLLOUT | POLLWRNORM);
	if (events & (POLLIN | POLLRDNORM)) {
		if (sc->sc_rd_count != 0) {
			DPRINTFN(2,("%s: have data\n", __func__));
			revents |= events & (POLLIN | POLLRDNORM);
		} else {
			DPRINTFN(2,("%s: recording select\n", __func__));
			selrecord(l, &sc->sc_rd_sel);
		}
	}
	splx(s);

	return (revents);
}
static int
auvitek_start_transfer(void *opaque)
{
	struct auvitek_softc *sc = opaque;
	int error, s;
	uint16_t vpos = 0, hpos = 0;
	uint16_t hres = 720 * 2;
	uint16_t vres = 484 / 2;

	auvitek_write_1(sc, AU0828_REG_SENSORVBI_CTL, 0x00);

	/* program video position and size */
	auvitek_write_1(sc, AU0828_REG_HPOS_LO, hpos & 0xff);
	auvitek_write_1(sc, AU0828_REG_HPOS_HI, hpos >> 8);
	auvitek_write_1(sc, AU0828_REG_VPOS_LO, vpos & 0xff);
	auvitek_write_1(sc, AU0828_REG_VPOS_HI, vpos >> 8);
	auvitek_write_1(sc, AU0828_REG_HRES_LO, hres & 0xff);
	auvitek_write_1(sc, AU0828_REG_HRES_HI, hres >> 8);
	auvitek_write_1(sc, AU0828_REG_VRES_LO, vres & 0xff);
	auvitek_write_1(sc, AU0828_REG_VRES_HI, vres >> 8);

	auvitek_write_1(sc, AU0828_REG_SENSOR_CTL, 0xb3);

	auvitek_write_1(sc, AU0828_REG_AUDIOCTL, 0x01);

	s = splusb();
	error = auvitek_start_xfer(sc);
	splx(s);

	if (error)
		auvitek_stop_transfer(sc);

	return error;
}
示例#6
0
void
ohci_voyager_attach_deferred(struct device *self)
{
	struct ohci_voyager_softc *sc = (struct ohci_voyager_softc *)self;
	usbd_status r;
	int s;

	s = splusb();

	sc->sc.sc_bus.dying = 0;
	
	r = ohci_init(&sc->sc);
	if (r != USBD_NORMAL_COMPLETION) {
		printf("%s: init failed, error=%d\n",
		    sc->sc.sc_bus.bdev.dv_xname, r);
		bus_space_unmap(sc->sc.iot, sc->sc.ioh, sc->sc.sc_size);
		splx(s);
		return;
	}

	splx(s);

	/* Attach usb device. */
	config_found(self, &sc->sc.sc_bus, usbctlprint);
}
示例#7
0
int
uhid_detach(struct device *self, int flags)
{
	struct uhid_softc *sc = (struct uhid_softc *)self;
	int s;
	int maj, mn;

	DPRINTF(("uhid_detach: sc=%p flags=%d\n", sc, flags));

	if (sc->sc_hdev.sc_state & UHIDEV_OPEN) {
		s = splusb();
		if (--sc->sc_refcnt >= 0) {
			/* Wake everyone */
			wakeup(&sc->sc_q);
			/* Wait for processes to go away. */
			usb_detach_wait(&sc->sc_hdev.sc_dev);
		}
		splx(s);
	}

	/* locate the major number */
	for (maj = 0; maj < nchrdev; maj++)
		if (cdevsw[maj].d_open == uhidopen)
			break;

	/* Nuke the vnodes for any open instances (calls close). */
	mn = self->dv_unit;
	vdevgone(maj, mn, mn, VCHR);

	return (0);
}
示例#8
0
void
kue_watchdog(struct ifnet *ifp)
{
	struct kue_softc	*sc = ifp->if_softc;
	struct kue_chain	*c;
	usbd_status		stat;
	int			s;

	DPRINTFN(5,("%s: %s: enter\n", sc->kue_dev.dv_xname,__func__));

	if (sc->kue_dying)
		return;

	ifp->if_oerrors++;
	printf("%s: watchdog timeout\n", sc->kue_dev.dv_xname);

	s = splusb();
	c = &sc->kue_cdata.kue_tx_chain[0];
	usbd_get_xfer_status(c->kue_xfer, NULL, NULL, NULL, &stat);
	kue_txeof(c->kue_xfer, c, stat);

	if (IFQ_IS_EMPTY(&ifp->if_snd) == 0)
		kue_start(ifp);
	splx(s);
}
示例#9
0
文件: udsir.c 项目: ryo/netbsd-src
static int
udsir_kqfilter(void *h, struct knote *kn)
{
	struct udsir_softc *sc = h;
	struct klist *klist;
	int s;

	switch (kn->kn_filter) {
	case EVFILT_READ:
		klist = &sc->sc_rd_sel.sel_klist;
		kn->kn_fop = &udsirread_filtops;
		break;
	case EVFILT_WRITE:
		klist = &sc->sc_wr_sel.sel_klist;
		kn->kn_fop = &udsirwrite_filtops;
		break;
	default:
		return (EINVAL);
	}

	kn->kn_hook = sc;

	s = splusb();
	SLIST_INSERT_HEAD(klist, kn, kn_selnext);
	splx(s);

	return (0);
}
示例#10
0
void
ohci_pci_attach_deferred(struct device *self)
{
	struct ohci_pci_softc *sc = (struct ohci_pci_softc *)self;
	usbd_status r;
	int s;

	s = splusb();

	sc->sc.sc_dying = 0;
	
	r = ohci_init(&sc->sc);
	if (r != USBD_NORMAL_COMPLETION) {
		printf("%s: init failed, error=%d\n",
		    sc->sc.sc_bus.bdev.dv_xname, r);
		bus_space_unmap(sc->sc.iot, sc->sc.ioh, sc->sc.sc_size);
		splx(s);
		return;
	}

	sc->sc.sc_powerhook = powerhook_establish(ohci_power, &sc->sc);
	if (sc->sc.sc_powerhook == NULL)
		printf("%s: unable to establish powerhook\n",
		    sc->sc.sc_bus.bdev.dv_xname);

	splx(s);

	/* Attach usb device. */
	sc->sc.sc_child = config_found((void *)sc, &sc->sc.sc_bus,
				       usbctlprint);
}
示例#11
0
int
ulpt_detach(struct device *self, int flags)
{
	struct ulpt_softc *sc = (struct ulpt_softc *)self;
	int s;
	int maj, mn;

	DPRINTF(("ulpt_detach: sc=%p\n", sc));

	if (sc->sc_out_pipe != NULL)
		usbd_abort_pipe(sc->sc_out_pipe);
	if (sc->sc_in_pipe != NULL)
		usbd_abort_pipe(sc->sc_in_pipe);

	s = splusb();
	if (--sc->sc_refcnt >= 0) {
		/* There is noone to wake, aborting the pipe is enough */
		/* Wait for processes to go away. */
		usb_detach_wait(&sc->sc_dev);
	}
	splx(s);

	/* locate the major number */
	for (maj = 0; maj < nchrdev; maj++)
		if (cdevsw[maj].d_open == ulptopen)
			break;

	/* Nuke the vnodes for any open instances (calls close). */
	mn = self->dv_unit;
	vdevgone(maj, mn, mn, VCHR);
	vdevgone(maj, mn | ULPT_NOPRIME , mn | ULPT_NOPRIME, VCHR);

	return (0);
}
示例#12
0
int
uhidkqfilter(dev_t dev, struct knote *kn)
{
	struct uhid_softc *sc;
	struct klist *klist;
	int s;

	sc = uhid_cd.cd_devs[UHIDUNIT(dev)];

	if (sc->sc_dying)
		return (EIO);

	switch (kn->kn_filter) {
	case EVFILT_READ:
		klist = &sc->sc_rsel.si_note;
		kn->kn_fop = &uhidread_filtops;
		break;

	case EVFILT_WRITE:
		klist = &sc->sc_rsel.si_note;
		kn->kn_fop = &uhid_seltrue_filtops;
		break;

	default:
		return (1);
	}

	kn->kn_hook = (void *)sc;

	s = splusb();
	SLIST_INSERT_HEAD(klist, kn, kn_selnext);
	splx(s);

	return (0);
}
示例#13
0
int
uirda_read(void *h, struct uio *uio, int flag)
{
	struct uirda_softc *sc = h;
	usbd_status err;
	int s;
	int error;
	u_int n;

	DPRINTFN(1,("%s: sc=%p\n", __func__, sc));

	if (sc->sc_dying)
		return (EIO);

#ifdef DIAGNOSTIC
	if (sc->sc_rd_buf == NULL)
		return (EINVAL);
#endif

	sc->sc_refcnt++;

	do {
		s = splusb();
		while (sc->sc_rd_count == 0) {
			DPRINTFN(5,("uirda_read: calling tsleep()\n"));
			error = tsleep(&sc->sc_rd_count, PZERO | PCATCH,
				       "uirdrd", 0);
			if (sc->sc_dying)
				error = EIO;
			if (error) {
				splx(s);
				DPRINTF(("uirda_read: tsleep() = %d\n", error));
				goto ret;
			}
		}
		splx(s);

		mutex_enter(&sc->sc_rd_buf_lk);
		n = sc->sc_rd_count - sc->sc_hdszi;
		DPRINTFN(1,("%s: sc=%p n=%u, hdr=0x%02x\n", __func__,
			    sc, n, sc->sc_rd_buf[0]));
		if (n > uio->uio_resid)
			error = EINVAL;
		else
			error = uiomove(sc->sc_rd_buf + sc->sc_hdszi, n, uio);
		sc->sc_rd_count = 0;
		mutex_exit(&sc->sc_rd_buf_lk);

		err = uirda_start_read(sc);
		/* XXX check err */

	} while (n == 0);

	DPRINTFN(1,("uirda_read: return %d\n", error));

 ret:
	if (--sc->sc_refcnt < 0)
		usb_detach_wakeup(USBDEV(sc->sc_dev));
	return (error);
}
示例#14
0
文件: ugen.c 项目: SylvestreG/bitrig
int
ugenpoll(dev_t dev, int events, struct proc *p)
{
	struct ugen_softc *sc;
	struct ugen_endpoint *sce;
	int revents = 0;
	int s;

	sc = ugen_cd.cd_devs[UGENUNIT(dev)];

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

	/* XXX always IN */
	sce = &sc->sc_endpoints[UGENENDPOINT(dev)][IN];
	if (sce == NULL)
		return (POLLERR);
#ifdef DIAGNOSTIC
	if (!sce->edesc) {
		printf("ugenpoll: no edesc\n");
		return (POLLERR);
	}
	if (!sce->pipeh) {
		printf("ugenpoll: no pipe\n");
		return (POLLERR);
	}
#endif
	s = splusb();
	switch (sce->edesc->bmAttributes & UE_XFERTYPE) {
	case UE_INTERRUPT:
		if (events & (POLLIN | POLLRDNORM)) {
			if (sce->q.c_cc > 0)
				revents |= events & (POLLIN | POLLRDNORM);
			else
				selrecord(p, &sce->rsel);
		}
		break;
	case UE_ISOCHRONOUS:
		if (events & (POLLIN | POLLRDNORM)) {
			if (sce->cur != sce->fill)
				revents |= events & (POLLIN | POLLRDNORM);
			else
				selrecord(p, &sce->rsel);
		}
		break;
	case UE_BULK:
		/*
		 * We have no easy way of determining if a read will
		 * yield any data or a write will happen.
		 * Pretend they will.
		 */
		revents |= events &
			   (POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM);
		break;
	default:
		break;
	}
	splx(s);
	return (revents);
}
示例#15
0
int
ugl_detach(struct device *self, int flags)
{
	struct ugl_softc	*sc = (struct ugl_softc *)self;
	struct ifnet		*ifp = GET_IFP(sc);
	int			s;

	DPRINTFN(2,("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__));

	s = splusb();

	if (ifp->if_flags & IFF_RUNNING)
		ugl_stop(sc);

	if (ifp->if_softc != NULL)
		if_detach(ifp);

#ifdef DIAGNOSTIC
	if (sc->sc_ep[UGL_ENDPT_TX] != NULL ||
	    sc->sc_ep[UGL_ENDPT_RX] != NULL ||
	    sc->sc_ep[UGL_ENDPT_INTR] != NULL)
		printf("%s: detach has active endpoints\n",
		       sc->sc_dev.dv_xname);
#endif

	splx(s);

	return (0);
}
示例#16
0
usbd_status
usbd_intr_transfer(usbd_xfer_handle xfer, usbd_pipe_handle pipe,
    u_int16_t flags, u_int32_t timeout, void *buf, u_int32_t *size, char *lbl)
{
	usbd_status err;
	int s, error;

	usbd_setup_xfer(xfer, pipe, 0, buf, *size, flags, timeout,
	    usbd_intr_transfer_cb);
	DPRINTFN(1, ("usbd_intr_transfer: start transfer %d bytes\n", *size));
	s = splusb();		/* don't want callback until tsleep() */
	err = usbd_transfer(xfer);
	if (err != USBD_IN_PROGRESS) {
		splx(s);
		return (err);
	}
	error = tsleep(xfer, PZERO | PCATCH, lbl, 0);
	splx(s);
	if (error) {
		DPRINTF(("usbd_intr_transfer: tsleep=%d\n", error));
		usbd_abort_pipe(pipe);
		return (USBD_INTERRUPTED);
	}
	usbd_get_xfer_status(xfer, NULL, NULL, size, &err);
	DPRINTFN(1,("usbd_intr_transfer: transferred %d\n", *size));
	if (err) {
		DPRINTF(("usbd_intr_transfer: error=%d\n", err));
		usbd_clear_endpoint_stall(pipe);
	}
	return (err);
}
示例#17
0
int
uhidpoll(dev_t dev, int events, struct proc *p)
{
	struct uhid_softc *sc;
	int revents = 0;
	int s;

	sc = uhid_cd.cd_devs[UHIDUNIT(dev)];

	if (sc->sc_dying)
		return (POLLERR);

	s = splusb();
	if (events & (POLLOUT | POLLWRNORM))
		revents |= events & (POLLOUT | POLLWRNORM);
	if (events & (POLLIN | POLLRDNORM)) {
		if (sc->sc_q.c_cc > 0)
			revents |= events & (POLLIN | POLLRDNORM);
		else
			selrecord(p, &sc->sc_rsel);
	}

	splx(s);
	return (revents);
}
示例#18
0
文件: uhid.c 项目: MarginC/kame
int
uhidpoll(dev_t dev, int events, usb_proc_ptr p)
{
	struct uhid_softc *sc;
	int revents = 0;
	int s;

	USB_GET_SC(uhid, UHIDUNIT(dev), sc);

	if (sc->sc_dying)
		return (EIO);

	s = splusb();
	if (events & (POLLOUT | POLLWRNORM))
		revents |= events & (POLLOUT | POLLWRNORM);
	if (events & (POLLIN | POLLRDNORM)) {
		if (sc->sc_q.c_cc > 0)
			revents |= events & (POLLIN | POLLRDNORM);
		else
			selrecord(p, &sc->sc_rsel);
	}

	splx(s);
	return (revents);
}
示例#19
0
int
uhid_do_read(struct uhid_softc *sc, struct uio *uio, int flag)
{
	int s;
	int error = 0;
	int extra;
	size_t length;
	u_char buffer[UHID_CHUNK];
	usbd_status err;

	DPRINTFN(1, ("uhidread\n"));
	if (sc->sc_state & UHID_IMMED) {
		DPRINTFN(1, ("uhidread immed\n"));
		extra = sc->sc_hdev.sc_report_id != 0;
		err = uhidev_get_report(&sc->sc_hdev, UHID_INPUT_REPORT,
		    sc->sc_hdev.sc_report_id, buffer,
		    sc->sc_hdev.sc_isize + extra);
		if (err)
			return (EIO);
		return (uiomove(buffer+extra, sc->sc_hdev.sc_isize, uio));
	}

	s = splusb();
	while (sc->sc_q.c_cc == 0) {
		if (flag & IO_NDELAY) {
			splx(s);
			return (EWOULDBLOCK);
		}
		sc->sc_state |= UHID_ASLP;
		DPRINTFN(5, ("uhidread: sleep on %p\n", &sc->sc_q));
		error = tsleep(&sc->sc_q, PZERO | PCATCH, "uhidrea", 0);
		DPRINTFN(5, ("uhidread: woke, error=%d\n", error));
		if (usbd_is_dying(sc->sc_hdev.sc_udev))
			error = EIO;
		if (error) {
			sc->sc_state &= ~UHID_ASLP;
			break;
		}
	}
	splx(s);

	/* Transfer as many chunks as possible. */
	while (sc->sc_q.c_cc > 0 && uio->uio_resid > 0 && !error) {
		length = min(sc->sc_q.c_cc, uio->uio_resid);
		if (length > sizeof(buffer))
			length = sizeof(buffer);

		/* Remove a small chunk from the input queue. */
		(void) q_to_b(&sc->sc_q, buffer, length);
		DPRINTFN(5, ("uhidread: got %lu chars\n", (u_long)length));

		/* Copy the data to the user process. */
		if ((error = uiomove(buffer, length, uio)) != 0)
			break;
	}

	return (error);
}
示例#20
0
文件: ugen.c 项目: SylvestreG/bitrig
void
filt_ugenrdetach(struct knote *kn)
{
	struct ugen_endpoint *sce = (void *)kn->kn_hook;
	int s;

	s = splusb();
	SLIST_REMOVE(&sce->rsel.si_note, kn, knote, kn_selnext);
	splx(s);
}
示例#21
0
/* disallow the access to the device */
static int
ukbd_disable(keyboard_t *kbd)
{
	int s;

	s = splusb();
	KBD_DEACTIVATE(kbd);
	splx(s);
	return 0;
}
示例#22
0
void
filt_uhidrdetach(struct knote *kn)
{
	struct uhid_softc *sc = (void *)kn->kn_hook;
	int s;

	s = splusb();
	SLIST_REMOVE(&sc->sc_rsel.si_note, kn, knote, kn_selnext);
	splx(s);
}
示例#23
0
void
umass_io_put(void *cookie, void *io)
{
	struct umass_scsi_softc *scbus = cookie;
	int s;

	s = splusb();
	scbus->sc_open = 0;
	splx(s);
}
示例#24
0
文件: udsir.c 项目: ryo/netbsd-src
static void
filt_udsirwdetach(struct knote *kn)
{
	struct udsir_softc *sc = kn->kn_hook;
	int s;

	s = splusb();
	SLIST_REMOVE(&sc->sc_wr_sel.sel_klist, kn, knote, kn_selnext);
	splx(s);
}
示例#25
0
static int
out_jack_output(struct umidi_jack *out_jack, u_char *src, int len, int cin)
{
	struct umidi_endpoint *ep = out_jack->endpoint;
	struct umidi_softc *sc = ep->sc;
	unsigned char *packet;
	int s;
	int plen;
	int poff;

	if (sc->sc_dying)
		return EIO;

	if (!out_jack->opened)
		return ENODEV; /* XXX as it was, is this the right errno? */

#ifdef UMIDI_DEBUG
	if ( umididebug >= 100 )
		microtime(&umidi_tv);
#endif
	DPRINTFN(100, ("umidi out: %lu.%06lus ep=%p cn=%d len=%d cin=%#x\n",
	    umidi_tv.tv_sec%100, umidi_tv.tv_usec,
	    ep, out_jack->cable_number, len, cin));
	
	s = splusb();
	packet = *ep->next_slot++;
	KASSERT(ep->buffer_size >=
	    (ep->next_slot - ep->buffer) * sizeof *ep->buffer);
	memset(packet, 0, UMIDI_PACKET_SIZE);
	if (UMQ_ISTYPE(sc, UMQ_TYPE_MIDIMAN_GARBLE)) {
		if (NULL != out_jack->midiman_ppkt) { /* fill out a prev pkt */
			poff = 0x0f & (out_jack->midiman_ppkt[3]);
			plen = 3 - poff;
			if (plen > len)
				plen = len;
			memcpy(out_jack->midiman_ppkt+poff, src, plen);
			src += plen;
			len -= plen;
			plen += poff;
			out_jack->midiman_ppkt[3] =
			    MIX_CN_CIN(out_jack->cable_number, plen);
			DPR_PACKET(out+, sc, out_jack->midiman_ppkt);
			if (3 == plen)
				out_jack->midiman_ppkt = NULL; /* no more */
		}
		if (0 == len)
			ep->next_slot--; /* won't be needed, nevermind */
		else {
			memcpy(packet, src, len);
			packet[3] = MIX_CN_CIN(out_jack->cable_number, len);
			DPR_PACKET(out, sc, packet);
			if (len < 3)
				out_jack->midiman_ppkt = packet;
		}
	} else { /* the nice simple USB class-compliant case */
示例#26
0
/*
 * Do not free the memory unconditionally since we might be called
 * from an interrupt context and that is BAD.
 * XXX when should we really free?
 */
static void
usb_block_freemem(usb_dma_block_t *p)
{
	int s;

	DPRINTFN(6, ("usb_block_freemem: size=%lu\n", (u_long)p->size));
	s = splusb();
	LIST_INSERT_HEAD(&usb_blk_freelist, p, next);
	usb_blk_nfree++;
	splx(s);
}
示例#27
0
/* detach */
int
url_detach(device_t self, int flags)
{
	struct url_softc *sc = device_private(self);
	struct ifnet *ifp = GET_IFP(sc);
	int s;

	DPRINTF(("%s: %s: enter\n", device_xname(sc->sc_dev), __func__));

	/* Detached before attached finished */
	if (!sc->sc_attached)
		return (0);

	callout_stop(&sc->sc_stat_ch);

	/* Remove any pending tasks */
	usb_rem_task(sc->sc_udev, &sc->sc_tick_task);
	usb_rem_task(sc->sc_udev, &sc->sc_stop_task);

	s = splusb();

	if (--sc->sc_refcnt >= 0) {
		/* Wait for processes to go away */
		usb_detach_waitold(sc->sc_dev);
	}

	if (ifp->if_flags & IFF_RUNNING)
		url_stop(GET_IFP(sc), 1);

	rnd_detach_source(&sc->rnd_source);
	mii_detach(&sc->sc_mii, MII_PHY_ANY, MII_OFFSET_ANY);
	ifmedia_delete_instance(&sc->sc_mii.mii_media, IFM_INST_ANY);
	ether_ifdetach(ifp);
	if_detach(ifp);

#ifdef DIAGNOSTIC
	if (sc->sc_pipe_tx != NULL)
		aprint_debug_dev(self, "detach has active tx endpoint.\n");
	if (sc->sc_pipe_rx != NULL)
		aprint_debug_dev(self, "detach has active rx endpoint.\n");
	if (sc->sc_pipe_intr != NULL)
		aprint_debug_dev(self, "detach has active intr endpoint.\n");
#endif

	sc->sc_attached = 0;

	splx(s);

	rw_destroy(&sc->sc_mii_rwlock);
	usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
			   sc->sc_dev);

	return (0);
}
示例#28
0
void
octohci_attach(struct device *parent, struct device *self, void *aux)
{
	struct octohci_softc *sc = (struct octohci_softc *)self;
	struct octuctl_attach_args *aa = aux;
	char *devname;
	uint64_t port_ctl;
	int rc;
	int s;

	sc->sc_ohci.iot = aa->aa_bust;
	sc->sc_ohci.sc_bus.pipe_size = sizeof(struct usbd_pipe);
	sc->sc_ohci.sc_bus.dmatag = aa->aa_dmat;

	rc = bus_space_map(sc->sc_ohci.iot, UCTL_OHCI_BASE, UCTL_OHCI_SIZE,
	    0, &sc->sc_ohci.ioh);
	KASSERT(rc == 0);

	port_ctl = bus_space_read_8(aa->aa_octuctl_bust, aa->aa_ioh,
	    UCTL_OHCI_CTL);
	port_ctl &= ~UCTL_OHCI_CTL_L2C_ADDR_MSB_MASK;
	port_ctl |= (1 << UCTL_OHCI_CTL_L2C_DESC_EMOD_SHIFT);
	port_ctl |= (1 << UCTL_OHCI_CTL_L2C_BUFF_EMOD_SHIFT);
	bus_space_write_8(aa->aa_octuctl_bust, aa->aa_ioh, UCTL_OHCI_CTL,
	    port_ctl);

	s = splusb();

	sc->sc_ohci.sc_id_vendor = 0;
	strlcpy(sc->sc_ohci.sc_vendor, "Octeon", sizeof(sc->sc_ohci.sc_vendor));

	sc->sc_ih = octeon_intr_establish(CIU_INT_USB, IPL_USB, ohci_intr,
	    (void *)&sc->sc_ohci, devname);
	KASSERT(sc->sc_ih != NULL);

	if ((ohci_checkrev(&sc->sc_ohci) != USBD_NORMAL_COMPLETION) ||
	    (ohci_handover(&sc->sc_ohci) != USBD_NORMAL_COMPLETION))
		goto failed;

	/* ignore interrupts for now */
	sc->sc_ohci.sc_bus.dying = 1;
	config_defer(self, octohci_attach_deferred);

	splx(s);
	return;

failed:
	octeon_intr_disestablish(sc->sc_ih);
	bus_space_unmap(sc->sc_ohci.iot, sc->sc_ohci.ioh, UCTL_OHCI_SIZE);
	splx(s);
	return;
}
示例#29
0
文件: umidi.c 项目: bluhm/sys
static void
free_all_jacks(struct umidi_softc *sc)
{
	int s, jacks = sc->sc_in_num_jacks + sc->sc_out_num_jacks;

	s = splusb();
	if (sc->sc_out_jacks) {
		free(sc->sc_jacks, M_USBDEV, jacks * sizeof(*sc->sc_out_jacks));
		sc->sc_jacks = sc->sc_in_jacks = sc->sc_out_jacks = NULL;
		sc->sc_out_num_jacks = sc->sc_in_num_jacks = 0;
	}
	splx(s);
}
示例#30
0
void
ukbd_cnpollc(void *v, int on)
{
	struct ukbd_softc *sc = v;

	DPRINTFN(2,("ukbd_cnpollc: sc=%p on=%d\n", v, on));

	if (on)
		sc->sc_spl = splusb();
	else
		splx(sc->sc_spl);
	usbd_set_polling(sc->sc_hdev.sc_udev, on);
}