示例#1
0
/*
 * write data from current packet to Transmit FIFO.
 * restart when done.
 */
static void
bt3c_transmit(struct bt3c_softc *sc)
{
	struct mbuf *m;
	int count, rlen;
	uint8_t *rptr;

	m = sc->sc_txp;
	if (m == NULL) {
		sc->sc_flags &= ~BT3C_XMIT;
		bt3c_start(sc);
		return;
	}

	count = 0;
	rlen = 0;
	rptr = mtod(m, uint8_t *);

	bt3c_set_address(sc, BT3C_TX_FIFO);

	for(;;) {
		if (rlen >= m->m_len) {
			m = m->m_next;
			if (m == NULL) {
				m = sc->sc_txp;
				sc->sc_txp = NULL;

				if (M_GETCTX(m, void *) == NULL)
					m_freem(m);
				else if (!hci_complete_sco(sc->sc_unit, m))
					sc->sc_stats.err_tx++;

				break;
			}
示例#2
0
/*
 * write data from current packet to Transmit FIFO.
 * restart when done.
 */
static void
btbc_transmit(struct btbc_softc *sc)
{
	hci_cmd_hdr_t *p;
	struct mbuf *m;
	int count, set_baudrate, n, s;
	uint32_t offset, command;
	uint8_t *rptr;

	m = sc->sc_txp;
	if (m == NULL) {
		sc->sc_flags &= ~BTBC_XMIT;
		btbc_start(sc);
		return;
	}

	set_baudrate = 0;
	p = mtod(m, hci_cmd_hdr_t *);
	if ((void *)m->m_pktdat == (void *)p) {
		const uint16_t opcode =
		    htole16(HCI_CMD_ERICSSON_SET_UART_BAUD_RATE);

		if (p->type == HCI_CMD_PKT &&
		    p->opcode == opcode &&
		    p->length == 1) {
			set_baudrate = 1;
			sc->sc_txp = NULL;	/* safe reentrant */
		}
	}

	count = 0;
	rptr = mtod(m, uint8_t *);
	for(;;) {
		if (m->m_len == 0) {
			m = m->m_next;
			if (m == NULL) {
				m = sc->sc_txp;
				sc->sc_txp = NULL;

				if (M_GETCTX(m, void *) == NULL)
					m_freem(m);
				else if (!hci_complete_sco(sc->sc_unit, m))
					sc->sc_stats.err_tx++;

				break;
			}
示例#3
0
void
ubt_xmit_sco_start1(struct ubt_softc *sc, struct ubt_isoc_xfer *isoc)
{
	struct mbuf *m;
	uint8_t *buf;
	int num, len, size, space;

	if (sc->sc_dying)
		return;

	space = sc->sc_scowr_size * UBT_NFRAMES;
	buf = isoc->buf;
	len = 0;

	/*
	 * Fill the request buffer with data from the queue,
	 * keeping any leftover packet on our private hook.
	 *
	 * Complete packets are passed back up to the stack
	 * for disposal, since we can't rely on the controller
	 * to tell us when it has finished with them.
	 */

	m = sc->sc_scowr_mbuf;
	while (space > 0) {
		if (m == NULL) {
			crit_enter();
			IF_DEQUEUE(&sc->sc_scowr_queue, m);
			crit_exit();
			if (m == NULL)
				break;

			m_adj(m, 1);	/* packet type */

		}

		if (m->m_pkthdr.len > 0) {
			size = MIN(m->m_pkthdr.len, space);

			m_copydata(m, 0, size, buf);
			m_adj(m, size);

			buf += size;
			len += size;
			space -= size;
		}

		if (m->m_pkthdr.len == 0) {
			sc->sc_stats.sco_tx++;
			if (!hci_complete_sco(sc->sc_unit, m))
				sc->sc_stats.err_tx++;

			m = NULL;
		}
	}
	sc->sc_scowr_mbuf = m;

	DPRINTFN(15, "isoc=%p, len=%d, space=%d\n", isoc, len, space);

	if (len == 0)	/* nothing to send */
	
		return;

	sc->sc_refcnt++;
	sc->sc_scowr_busy = 1;
	sc->sc_stats.byte_tx += len;
	isoc->busy = 1;

	/*
	 * calculate number of isoc frames and sizes
	 */

	for (num = 0 ; len > 0 ; num++) {
		size = MIN(sc->sc_scowr_size, len);

		isoc->size[num] = size;
		len -= size;
	}

	usbd_setup_isoc_xfer(isoc->xfer,
			     sc->sc_scowr_pipe,
			     isoc,
			     isoc->size,
			     num,
			     USBD_NO_COPY | USBD_FORCE_SHORT_XFER,
			     ubt_xmit_sco_complete);

	usbd_transfer(isoc->xfer);
}