Beispiel #1
0
int
ucomopen(dev_t dev, int flag, int mode, struct proc *p)
{
	int unit = UCOMUNIT(dev);
	struct ucom_softc *sc;
	int error;

	if (unit >= ucom_cd.cd_ndevs)
		return (ENXIO);
	sc = ucom_cd.cd_devs[unit];
	if (sc == NULL)
		return (ENXIO);

	if (usbd_is_dying(sc->sc_uparent))
		return (EIO);

	if (ISSET(sc->sc_dev.dv_flags, DVF_ACTIVE) == 0)
		return (ENXIO);

	sc->sc_refcnt++;
	error = ucom_do_open(dev, flag, mode, p);
	if (--sc->sc_refcnt < 0)
		usb_detach_wakeup(&sc->sc_dev);

	return (error);
}
Beispiel #2
0
int
umass_scsi_attach(struct umass_softc *sc)
{
	struct scsibus_attach_args saa;
	struct umass_scsi_softc *scbus;

	scbus = umass_scsi_setup(sc);
	scbus->sc_link.adapter_target = UMASS_SCSIID_HOST;
	scbus->sc_link.luns = sc->maxlun + 1;
	scbus->sc_link.flags &= ~SDEV_ATAPI;
	scbus->sc_link.flags |= SDEV_UMASS;

	bzero(&saa, sizeof(saa));
	saa.saa_sc_link = &scbus->sc_link;

	DPRINTF(UDMASS_USB, ("%s: umass_attach_bus: SCSI\n"
			     "sc = 0x%x, scbus = 0x%x\n",
			     sc->sc_dev.dv_xname, sc, scbus));

	sc->sc_refcnt++;
	scbus->base.sc_child =
	  config_found((struct device *)sc, &saa, scsiprint);
	if (--sc->sc_refcnt < 0)
		usb_detach_wakeup(&sc->sc_dev);

	return (0);
}
Beispiel #3
0
void
ubt_xmit_acl_complete(usbd_xfer_handle xfer,
		usbd_private_handle h, usbd_status status)
{
	struct ubt_softc *sc = h;

	DPRINTFN(15, "%s: ACL complete status=%s (%d)\n",
	    device_get_nameunit(sc->sc_dev), usbd_errstr(status), status);

	sc->sc_aclwr_busy = 0;

	if (--sc->sc_refcnt < 0) {
		usb_detach_wakeup(sc->sc_dev);
		return;
	}

	if (sc->sc_dying)
		return;

	if (status != USBD_NORMAL_COMPLETION) {
		DPRINTF("status=%s (%d)\n",
			usbd_errstr(status), status);

		sc->sc_stats.err_tx++;

		if (status == USBD_STALLED)
			usbd_clear_endpoint_stall_async(sc->sc_aclwr_pipe);
		else
			return;
	}

	ubt_xmit_acl_start(sc);
	
}
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);
}
Beispiel #5
0
int
wi_usb_do_transmit_sync(struct wi_usb_softc *sc, struct wi_usb_chain *c,
    void *ident)
{
	usbd_status		err;

	DPRINTFN(10,("%s: %s:\n",
	    sc->wi_usb_dev.dv_xname, __func__));

	sc->wi_usb_refcnt++;
	err = usbd_transfer(c->wi_usb_xfer);
	if (err != USBD_IN_PROGRESS && err != USBD_NORMAL_COMPLETION) {
		printf("%s: %s error=%s\n",
		    sc->wi_usb_dev.dv_xname, __func__,
		    usbd_errstr(err));
		/* Stop the interface from process context. */
		wi_usb_stop(sc);
		err = EIO;
		goto done;
	}
	err = tsleep(ident, PRIBIO, "wiTXsync", hz*1);
	if (err) {
		DPRINTFN(1,("%s: %s: err %x\n",
		    sc->wi_usb_dev.dv_xname, __func__, err));
		err = ETIMEDOUT;
	}
done:
	if (--sc->wi_usb_refcnt < 0)
		usb_detach_wakeup(&sc->wi_usb_dev);
	return err;
}
Beispiel #6
0
void
wi_usb_intr(struct usbd_xfer *xfer, void *priv, usbd_status status)
{
	struct wi_usb_softc	*sc = priv;

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

	if (usbd_is_dying(sc->wi_usb_udev))
		return;

	if (status != USBD_NORMAL_COMPLETION) {
		if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
			return;

		if (status == USBD_STALLED) {
			sc->wi_usb_refcnt++;
			usbd_clear_endpoint_stall_async(
			    sc->wi_usb_ep[WI_USB_ENDPT_RX]);
			if (--sc->wi_usb_refcnt < 0)
				usb_detach_wakeup(&sc->wi_usb_dev);
		}
		return;
	}
	/* XXX oerrors or collisions? */
}
Beispiel #7
0
int
uriowrite(dev_t dev, struct uio *uio, int flag)
{
	struct urio_softc *sc;
	struct usbd_xfer *xfer;
	usbd_status err;
	void *bufp;
	u_int32_t n;
	int error = 0;

	sc = urio_cd.cd_devs[URIOUNIT(dev)];

	DPRINTFN(5, ("uriowrite: unit=%d, len=%ld\n", URIOUNIT(dev),
		     (long)uio->uio_resid));

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

	xfer = usbd_alloc_xfer(sc->sc_udev);
	if (xfer == NULL)
		return (ENOMEM);
	bufp = usbd_alloc_buffer(xfer, URIO_BSIZE);
	if (bufp == NULL) {
		usbd_free_xfer(xfer);
		return (ENOMEM);
	}

	sc->sc_refcnt++;

	while ((n = min(URIO_BSIZE, uio->uio_resid)) != 0) {
		error = uiomove(bufp, n, uio);
		if (error)
			break;

		DPRINTFN(1, ("uriowrite: transfer %d bytes\n", n));

		usbd_setup_xfer(xfer, sc->sc_out_pipe, 0, bufp, n,
		    USBD_NO_COPY | USBD_SYNCHRONOUS, URIO_RW_TIMEOUT, NULL);
		err = usbd_transfer(xfer);
		DPRINTFN(2, ("uriowrite: err=%d\n", err));
		if (err) {
			usbd_clear_endpoint_stall(sc->sc_out_pipe);
			if (err == USBD_TIMEOUT)
				error = ETIMEDOUT;
			else
				error = EIO;
			break;
		}
	}

	usbd_free_xfer(xfer);

	if (--sc->sc_refcnt < 0)
		usb_detach_wakeup(&sc->sc_dev);

	DPRINTFN(5, ("uriowrite: done unit=%d, error=%d\n", URIOUNIT(dev),
		     error));

	return (error);
}
Beispiel #8
0
void
ucom_unlock(struct ucom_softc *sc)
{
	rw_exit_write(&sc->sc_lock);
	if (--sc->sc_refcnt < 0)
		usb_detach_wakeup(&sc->sc_dev);
}
Beispiel #9
0
Static void
ucom_unlock(struct ucom_softc *sc)
{
    usb_lockmgr(&sc->sc_lock, LK_RELEASE, NULL, curproc);
    if (--sc->sc_refcnt < 0)
        usb_detach_wakeup(USBDEV(sc->sc_dev));
}
Beispiel #10
0
Static void
url_unlock_mii(struct url_softc *sc)
{
	DPRINTFN(0xff, ("%s: %s: enter\n", USBDEVNAME(sc->sc_dev),
		       __func__));

	usb_lockmgr(&sc->sc_mii_lock, LK_RELEASE, NULL, curproc);
	if (--sc->sc_refcnt < 0)
		usb_detach_wakeup(USBDEV(sc->sc_dev));
}
Beispiel #11
0
void
ubt_recv_acl_complete(usbd_xfer_handle xfer,
		usbd_private_handle h, usbd_status status)
{
	struct ubt_softc *sc = h;
	struct mbuf *m;
	uint32_t count;
	void *buf;

	DPRINTFN(15, "sc=%p status=%s (%d)\n",
			sc, usbd_errstr(status), status);

	sc->sc_aclrd_busy = 0;

	if (--sc->sc_refcnt < 0) {
		DPRINTF("refcnt = %d\n", sc->sc_refcnt);
		usb_detach_wakeup(sc->sc_dev);
		return;
	}

	if (sc->sc_dying) {
		DPRINTF("sc_dying\n");
		return;
	}

	if (status != USBD_NORMAL_COMPLETION) {
		DPRINTF("status=%s (%d)\n",
			usbd_errstr(status), status);

		sc->sc_stats.err_rx++;

		if (status == USBD_STALLED)
			usbd_clear_endpoint_stall_async(sc->sc_aclrd_pipe);
		else
			return;
	} else {
		usbd_get_xfer_status(xfer, NULL, &buf, &count, NULL);

		if (count < sizeof(hci_acldata_hdr_t) - 1) {
			DPRINTF("dumped undersized packet (%d)\n", count);
			sc->sc_stats.err_rx++;
		} else {
			sc->sc_stats.acl_rx++;
			sc->sc_stats.byte_rx += count;

			m = ubt_mbufload(buf, count, HCI_ACL_DATA_PKT);
			if (m == NULL || !hci_input_acl(sc->sc_unit, m))
				sc->sc_stats.err_rx++;
		}
	}

	/* and restart */
	ubt_recv_acl_start(sc);
}
int
uirda_write(void *h, struct uio *uio, int flag)
{
	struct uirda_softc *sc = h;
	usbd_status err;
	u_int32_t n;
	int error = 0;

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

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

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

	n = uio->uio_resid;
	if (n > sc->sc_params.maxsize)
		return (EINVAL);

	sc->sc_refcnt++;
	mutex_enter(&sc->sc_wr_buf_lk);

	sc->sc_wr_buf[0] = UIRDA_EB_NO_CHANGE | UIRDA_NO_SPEED;
	error = uiomove(sc->sc_wr_buf + UIRDA_OUTPUT_HEADER_SIZE, n, uio);
	if (!error) {
		DPRINTFN(1, ("uirdawrite: transfer %d bytes\n", n));

		n += UIRDA_OUTPUT_HEADER_SIZE;
		err = usbd_bulk_transfer(sc->sc_wr_xfer, sc->sc_wr_pipe,
			  USBD_FORCE_SHORT_XFER | USBD_NO_COPY,
			  UIRDA_WR_TIMEOUT,
			  sc->sc_wr_buf, &n, "uirdawr");
		DPRINTFN(2, ("uirdawrite: err=%d\n", err));
		if (err) {
			if (err == USBD_INTERRUPTED)
				error = EINTR;
			else if (err == USBD_TIMEOUT)
				error = ETIMEDOUT;
			else
				error = EIO;
		}
	}

	mutex_exit(&sc->sc_wr_buf_lk);
	if (--sc->sc_refcnt < 0)
		usb_detach_wakeup(USBDEV(sc->sc_dev));

	DPRINTFN(1,("%s: sc=%p done\n", __func__, sc));
	return (error);
}
Beispiel #13
0
int
ucomioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
{
	struct ucom_softc *sc = device_lookup_private(&ucom_cd, UCOMUNIT(dev));
	int error;

	sc->sc_refcnt++;
	error = ucom_do_ioctl(sc, cmd, data, flag, l);
	if (--sc->sc_refcnt < 0)
		usb_detach_wakeup(USBDEV(sc->sc_dev));
	return (error);
}
Beispiel #14
0
int
ucomioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
{
	struct ucom_softc *sc = ucom_cd.cd_devs[UCOMUNIT(dev)];
	int error;

	sc->sc_refcnt++;
	error = ucom_do_ioctl(sc, cmd, data, flag, p);
	if (--sc->sc_refcnt < 0)
		usb_detach_wakeup(&sc->sc_dev);
	return (error);
}
Beispiel #15
0
int
uhidioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
{
	struct uhid_softc *sc;
	int error;

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

	sc->sc_refcnt++;
	error = uhid_do_ioctl(sc, cmd, addr, flag, p);
	if (--sc->sc_refcnt < 0)
		usb_detach_wakeup(&sc->sc_hdev.sc_dev);
	return (error);
}
Beispiel #16
0
int
uscannerwrite(dev_t dev, struct uio *uio, int flag)
{
	struct uscanner_softc *sc;
	int error;

	USB_GET_SC(uscanner, USCANNERUNIT(dev), sc);

	sc->sc_refcnt++;
	error = uscanner_do_write(sc, uio, flag);
	if (--sc->sc_refcnt < 0)
		usb_detach_wakeup(USBDEV(sc->sc_dev));
	return (error);
}
Beispiel #17
0
int
uhidwrite(dev_t dev, struct uio *uio, int flag)
{
	struct uhid_softc *sc;
	int error;

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

	sc->sc_refcnt++;
	error = uhid_do_write(sc, uio, flag);
	if (--sc->sc_refcnt < 0)
		usb_detach_wakeup(USBDEV(sc->sc_dev));
	return (error);
}
Beispiel #18
0
int
uhidioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, usb_proc_ptr p)
{
	struct uhid_softc *sc;
	int error;

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

	sc->sc_refcnt++;
	error = uhid_do_ioctl(sc, cmd, addr, flag, p);
	if (--sc->sc_refcnt < 0)
		usb_detach_wakeup(USBDEV(sc->sc_dev));
	return (error);
}
Beispiel #19
0
void
wi_usb_txeof_frm(struct usbd_xfer *xfer, void *priv,
    usbd_status status)
{
	struct wi_usb_chain	*c = priv;
	struct wi_usb_softc	*sc = c->wi_usb_sc;
	struct wi_softc		*wsc = &sc->sc_wi;
	struct ifnet		*ifp = &wsc->sc_ic.ic_if;

	int			s;
	int			err = 0;

	if (usbd_is_dying(sc->wi_usb_udev))
		return;

	s = splnet();

	DPRINTFN(10,("%s: %s: enter status=%d\n", sc->wi_usb_dev.dv_xname,
		    __func__, status));

	if (status != USBD_NORMAL_COMPLETION) {
		if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
			splx(s);
			return;
		}
		printf("%s: usb error on tx: %s\n", sc->wi_usb_dev.dv_xname,
		    usbd_errstr(status));
		if (status == USBD_STALLED) {
			sc->wi_usb_refcnt++;
			usbd_clear_endpoint_stall_async(
			    sc->wi_usb_ep[WI_USB_ENDPT_TX]);
			if (--sc->wi_usb_refcnt < 0)
				usb_detach_wakeup(&sc->wi_usb_dev);
		}
		splx(s);
		return;
	}

	if (status)
		err = WI_EV_TX_EXC;

	wi_txeof(wsc, err);

	wi_usb_tx_unlock(sc);

	if (!IFQ_IS_EMPTY(&ifp->if_snd))
		wi_start_usb(ifp);

	splx(s);
}
Beispiel #20
0
int
uhidwrite(dev_t dev, struct uio *uio, int flag)
{
	struct uhid_softc *sc;
	int error;

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

	sc->sc_refcnt++;
	error = uhid_do_write(sc, uio, flag);
	if (--sc->sc_refcnt < 0)
		usb_detach_wakeup(&sc->sc_hdev.sc_dev);
	return (error);
}
Beispiel #21
0
int
ugenwrite(dev_t dev, struct uio *uio, int flag)
{
	int endpt = UGENENDPOINT(dev);
	struct ugen_softc *sc;
	int error;

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

	sc->sc_refcnt++;
	error = ugen_do_write(sc, endpt, uio, flag);
	if (--sc->sc_refcnt < 0)
		usb_detach_wakeup(&sc->sc_dev);
	return (error);
}
Beispiel #22
0
int
ugenioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
{
	int endpt = UGENENDPOINT(dev);
	struct ugen_softc *sc;
	int error;

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

	sc->sc_refcnt++;
	error = ugen_do_ioctl(sc, endpt, cmd, addr, flag, p);
	if (--sc->sc_refcnt < 0)
		usb_detach_wakeup(&sc->sc_dev);
	return (error);
}
Beispiel #23
0
void
ubt_xmit_sco_complete(usbd_xfer_handle xfer,
		usbd_private_handle h, usbd_status status)
{
	struct ubt_isoc_xfer *isoc = h;
	struct ubt_softc *sc;
	int i;

	KKASSERT(xfer == isoc->xfer);
	sc = isoc->softc;

	DPRINTFN(15, "isoc=%p, status=%s (%d)\n",
		isoc, usbd_errstr(status), status);

	isoc->busy = 0;

	for (i = 0 ; ; i++) {
		if (i == UBT_NXFERS) {
			sc->sc_scowr_busy = 0;
			break;
		}

		if (sc->sc_scowr[i].busy)
			break;
	}

	if (--sc->sc_refcnt < 0) {
		usb_detach_wakeup(sc->sc_dev);
		return;
	}

	if (sc->sc_dying)
		return;

	if (status != USBD_NORMAL_COMPLETION) {
		DPRINTF("status=%s (%d)\n",
			usbd_errstr(status), status);

		sc->sc_stats.err_tx++;

		if (status == USBD_STALLED)
			usbd_clear_endpoint_stall_async(sc->sc_scowr_pipe);
		else
			return;
	}

	ubt_xmit_sco_start(sc);
}
Beispiel #24
0
int
ucomclose(dev_t dev, int flag, int mode, struct proc *p)
{
	struct ucom_softc *sc = ucom_cd.cd_devs[UCOMUNIT(dev)];
	int error;

	if (sc == NULL || usbd_is_dying(sc->sc_uparent))
		return (EIO);

	sc->sc_refcnt++;
	error = ucom_do_close(sc, flag, mode, p);
	if (--sc->sc_refcnt < 0)
		usb_detach_wakeup(&sc->sc_dev);

	return (error);
}
Beispiel #25
0
int
ucomwrite(dev_t dev, struct uio *uio, int flag)
{
	struct ucom_softc *sc = ucom_cd.cd_devs[UCOMUNIT(dev)];
	struct tty *tp = sc->sc_tty;
	int error;

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

	sc->sc_refcnt++;
	error = (*LINESW(tp, l_write))(tp, uio, flag);
	if (--sc->sc_refcnt < 0)
		usb_detach_wakeup(&sc->sc_dev);
	return (error);
}
Beispiel #26
0
int
ucompoll(dev_t dev, int events, struct lwp *l)
{
	struct ucom_softc *sc = device_lookup_private(&ucom_cd, UCOMUNIT(dev));
	struct tty *tp = sc->sc_tty;
	int revents;

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

	sc->sc_refcnt++;
	revents = ((*tp->t_linesw->l_poll)(tp, events, l));
	if (--sc->sc_refcnt < 0)
		usb_detach_wakeup(USBDEV(sc->sc_dev));
	return (revents);
}
Beispiel #27
0
int
ucomwrite(dev_t dev, struct uio *uio, int flag)
{
	struct ucom_softc *sc = device_lookup_private(&ucom_cd, UCOMUNIT(dev));
	struct tty *tp = sc->sc_tty;
	int error;

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

	sc->sc_refcnt++;
	error = ((*tp->t_linesw->l_write)(tp, uio, flag));
	if (--sc->sc_refcnt < 0)
		usb_detach_wakeup(USBDEV(sc->sc_dev));
	return (error);
}
Beispiel #28
0
int
ucomread(dev_t dev, struct uio *uio, int flag)
{
	struct ucom_softc *sc = ucom_cd.cd_devs[UCOMUNIT(dev)];
	struct tty *tp;
	int error;

	if (sc == NULL || usbd_is_dying(sc->sc_uparent))
		return (EIO);

	sc->sc_refcnt++;
	tp = sc->sc_tty;
	error = (*LINESW(tp, l_read))(tp, uio, flag);
	if (--sc->sc_refcnt < 0)
		usb_detach_wakeup(&sc->sc_dev);
	return (error);
}
Beispiel #29
0
Static void
url_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
{
	struct url_chain *c = priv;
	struct url_softc *sc = c->url_sc;
	struct ifnet *ifp = GET_IFP(sc);
	int s;

	if (sc->sc_dying)
		return;

	s = splnet();

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

	ifp->if_timer = 0;
	ifp->if_flags &= ~IFF_OACTIVE;

	if (status != USBD_NORMAL_COMPLETION) {
		if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
			splx(s);
			return;
		}
		ifp->if_oerrors++;
		printf("%s: usb error on tx: %s\n", USBDEVNAME(sc->sc_dev),
		       usbd_errstr(status));
		if (status == USBD_STALLED) {
			sc->sc_refcnt++;
			usbd_clear_endpoint_stall_async(sc->sc_pipe_tx);
			if (--sc->sc_refcnt < 0)
				usb_detach_wakeup(USBDEV(sc->sc_dev));
		}
		splx(s);
		return;
	}

	ifp->if_opackets++;

	m_freem(c->url_mbuf);
	c->url_mbuf = NULL;

	if (IFQ_IS_EMPTY(&ifp->if_snd) == 0)
		url_start(ifp);

	splx(s);
}
Beispiel #30
0
Static int
url_send(struct url_softc *sc, struct mbuf *m, int idx)
{
	int total_len;
	struct url_chain *c;
	usbd_status err;

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

	c = &sc->sc_cdata.url_tx_chain[idx];

	/* Copy the mbuf data into a contiguous buffer */
	m_copydata(m, 0, m->m_pkthdr.len, c->url_buf);
	c->url_mbuf = m;
	total_len = m->m_pkthdr.len;

	if (total_len < URL_MIN_FRAME_LEN) {
		bzero(c->url_buf + total_len, URL_MIN_FRAME_LEN - total_len);
		total_len = URL_MIN_FRAME_LEN;
	}
	usbd_setup_xfer(c->url_xfer, sc->sc_pipe_tx, c, c->url_buf, total_len,
			USBD_FORCE_SHORT_XFER | USBD_NO_COPY,
			URL_TX_TIMEOUT, url_txeof);

	/* Transmit */
	sc->sc_refcnt++;
	err = usbd_transfer(c->url_xfer);
	if (--sc->sc_refcnt < 0)
		usb_detach_wakeup(USBDEV(sc->sc_dev));
	if (err != USBD_IN_PROGRESS) {
		printf("%s: url_send error=%s\n", USBDEVNAME(sc->sc_dev),
		       usbd_errstr(err));
		/* Stop the interface */
		usb_add_task(sc->sc_udev, &sc->sc_stop_task);
		return (EIO);
	}

	DPRINTF(("%s: %s: send %d bytes\n", USBDEVNAME(sc->sc_dev),
		 __func__, total_len));

	sc->sc_cdata.url_tx_cnt++;

	return (0);
}