Пример #1
0
// Read file descriptor to buffer
BSP_DECLARE(ssize_t) bsp_buffer_io_read(BSP_BUFFER *b, int fd, size_t len)
{
    if (!b || !fd || !len)
    {
        return 0;
    }

    size_t need = B_LEN(b) + len;
    if (need > B_SIZE(b))
    {
        if (BSP_RTN_SUCCESS != _enlarge_buffer(b, need))
        {
            // Enlarge error
            return 0;
        }
    }

    // Try read
    ssize_t ret = read(fd, B_DATA(b) + B_LEN(b), len);
    if (ret > 0)
    {
        bsp_trace_message(BSP_TRACE_DEBUG, _tag_, "Read %d bytes from fd %d to buffer", (int) ret, fd);
        B_LEN(b) += ret;
    }

    return ret;
}
Пример #2
0
// Append data to buffer
BSP_DECLARE(size_t) bsp_buffer_append(BSP_BUFFER *b, const char *data, ssize_t len)
{
    if (!b || !data || B_ISCONST(b))
    {
        return 0;
    }

    if (len < 0)
    {
        len = strnlen(data, _BSP_MAX_UNSIZED_STRLEN);
    }

    size_t need = B_LEN(b) + len;
    if (need > B_SIZE(b))
    {
        // Space not enough, realloc buffer
        if (BSP_RTN_SUCCESS != _enlarge_buffer(b, need))
        {
            // Enlarge error
            return 0;
        }
    }

    memcpy(B_DATA(b) + B_LEN(b), data, len);
    B_LEN(b) = need;

    return len;
}
Пример #3
0
// Cancellation a buffer
BSP_DECLARE(void) bsp_del_buffer(BSP_BUFFER *b)
{
    if (b)
    {
        if (!B_ISCONST(b))
        {
            if (_BSP_BUFFER_HIGHWATER < B_SIZE(b))
            {
                // Buffer too big, just clean
                bsp_free(B_DATA(b));
                B_DATA(b) = NULL;
                B_SIZE(b) = 0;
                B_LEN(b) = 0;
                B_NOW(b) = 0;
            }

            if (_BSP_BUFFER_UNSATURATION < (B_SIZE(b) - B_LEN(b)))
            {
                _shrink_buffer(b);
            }
        }
        else
        {
            B_DATA(b) = NULL;
            B_SIZE(b) = 0;
        }

        bsp_mempool_free(mp_buffer, (void *) b);
    }

    return;
}
Пример #4
0
// Read all data from file descriptor to buffer
BSP_DECLARE(ssize_t) bsp_buffer_io_read_all(BSP_BUFFER *b, int fd)
{
    if (!b || !fd)
    {
        return 0;
    }

    ssize_t len = 0, tlen = 0;
    while (BSP_TRUE)
    {
        size_t need = B_LEN(b) + _BSP_FD_READ_ONCE;
        if (need > B_SIZE(b))
        {
            if (BSP_RTN_SUCCESS != _enlarge_buffer(b, need))
            {
                // Enlarge error
                break;
            }
        }

        len = read(fd, B_DATA(b) + B_LEN(b), _BSP_FD_READ_ONCE);
        if (len < 0)
        {
            if (EINTR == errno || EWOULDBLOCK == errno || EAGAIN == errno)
            {
                 // Break
                break;
            }
        }
        else if (0 == len)
        {
            // TCP FIN
            tlen = 0;
            break;
        }
        else
        {
            // Data already in buffer -_-
            tlen += len;
            B_LEN(b) += len;
            bsp_trace_message(BSP_TRACE_DEBUG, _tag_, "Read %d bytes from fd %d to buffer", (int) len, fd);
            if (len < _BSP_FD_READ_ONCE)
            {
                // All gone
                break;
            }
        }
    }

    return tlen;
}
Пример #5
0
int ct_send_packet (ct_chan_t *c, unsigned char *data, int len,
	void *attachment)
{
	int dsr, ne;

	if (len > DMABUFSZ)
		return -2;

	/* Is it really free? */
	ne = (c->te+1) % NBUF;
	if (ne == c->tn)
		return -1;

	/* Set up the tx descriptor. */
	B_LEN (c->tdesc[c->te]) = len;
	B_STATUS (c->tdesc[c->te]) = FST_EOM;
	c->attach[c->te] = attachment;
	if (c->tbuf[c->te] != data)
		memcpy (c->tbuf[c->te], data, len);

	/* Start the transmitter. */
	c->te = ne;
	outw (c->TX.EDA, (unsigned short) c->tdphys[ne]);
	dsr = inb (c->TX.DSR);
	if (! (dsr & DSR_DMA_ENABLE))
		outb (c->TX.DSR, DSR_DMA_ENABLE);
	return 0;
}
Пример #6
0
// Set const data to en empty buffer
BSP_DECLARE(size_t) bsp_buffer_set_const(BSP_BUFFER *b, const char *data, ssize_t len)
{
    if (!b || !data || B_ISCONST(b))
    {
        return 0;
    }

    if (len < 0)
    {
        len = strnlen(data, _BSP_MAX_UNSIZED_STRLEN);
    }

    if (B_DATA(b))
    {
        bsp_free(B_DATA(b));
    }

    B_DATA(b) = (char *) data;
    B_SIZE(b) = 0;
    B_LEN(b) = len;

    // Set to const
    b->is_const = BSP_TRUE;

    return len;
}
Пример #7
0
BSP_PRIVATE(int) _shrink_buffer(BSP_BUFFER *b)
{
    if (b)
    {
        size_t new_size = 2 << (int) log2(B_LEN(b));
        if (new_size < B_SIZE(b))
        {
            char *new_data = bsp_realloc(B_DATA(b), new_size);
            if (new_data)
            {
                B_DATA(b) = new_data;
                B_SIZE(b) = new_size;

                return BSP_RTN_SUCCESS;
            }

            return BSP_RTN_ERR_MEMORY;
        }
        else
        {
            // May not shrink
            return BSP_RTN_SUCCESS;
        }
    }

    return BSP_RTN_ERR_GENERAL;
}
Пример #8
0
// New buffer
BSP_DECLARE(BSP_BUFFER *) bsp_new_buffer()
{
    BSP_BUFFER *b = bsp_mempool_alloc(mp_buffer);
    if (b)
    {
        B_LEN(b) = 0;
        B_NOW(b) = 0;
        b->is_const = BSP_FALSE;
    }

    return b;
}
Пример #9
0
// Fill seriate character to buffer
BSP_DECLARE(size_t) bsp_buffer_fill(BSP_BUFFER *b, int code, size_t len)
{
    if (!b || !len)
    {
        return 0;
    }

    size_t need = B_LEN(b) + len;
    if (need > B_SIZE(b))
    {
        if (BSP_RTN_SUCCESS != _enlarge_buffer(b, need))
        {
            // Enlarge error
            return 0;
        }
    }

    memset(B_DATA(b) + B_LEN(b), code, len);
    B_LEN(b) = need;

    return len;
}
Пример #10
0
// Clear buffer data
BSP_DECLARE(void) bsp_clear_buffer(BSP_BUFFER *b)
{
    if (b)
    {
        B_LEN(b) = 0;
        B_NOW(b) = 0;

        if (B_ISCONST(b))
        {
            b->is_const = BSP_FALSE;
            b->data = NULL;
        }
    }

    return;
}
Пример #11
0
static void ct_hdlc_interrupt (ct_chan_t *c, int imvr)
{
	int i, dsr, st1, st2, cda;

	switch (imvr & IMVR_VECT_MASK) {
	case IMVR_RX_DMOK:		/* receive DMA normal end */
		dsr = inb (c->RX.DSR);
		cda = inw (c->RX.CDA);
		for (i=0; i<NBUF; ++i)
			if (cda == (unsigned short) c->rdphys[i])
				break;
		if (i >= NBUF)
			i = c->rn; /* cannot happen */
		while (c->rn != i) {
			int cst = B_STATUS (c->rdesc[c->rn]);
			if (cst == FST_EOM) {
				/* process data */
				if (c->call_on_rx)
					 c->call_on_rx (c, c->rbuf[c->rn],
						B_LEN(c->rdesc[c->rn]));
				++c->ipkts;
				c->ibytes += B_LEN(c->rdesc[c->rn]);
			} else if (cst & ST2_OVRN) {
				/* Receive overrun error */
				if (c->call_on_err)
					c->call_on_err (c, CT_OVERRUN);
				++c->ierrs;
			} else if (cst & (ST2_HDLC_RBIT |
				ST2_HDLC_ABT | ST2_HDLC_SHRT)) {
				/* Receive frame error */
				if (c->call_on_err)
					c->call_on_err (c, CT_FRAME);
				++c->ierrs;
			} else if ((cst & ST2_HDLC_EOM)
				&& (cst & ST2_HDLC_CRCE)) {
				/* Receive CRC error */
				if (c->call_on_err)
					c->call_on_err (c, CT_CRC);
				++c->ierrs;
			} else if (! (cst & ST2_HDLC_EOM)) {
				/* Frame dose not fit in the buffer.*/
				if (c->call_on_err)
					c->call_on_err (c, CT_OVERFLOW);
				++c->ierrs;
			}

			B_NEXT (c->rdesc[c->rn]) =
				c->rdphys[(c->rn+1) % NBUF] & 0xffff;
			B_PTR (c->rdesc[c->rn]) = c->rphys[c->rn];
			B_LEN (c->rdesc[c->rn]) = DMABUFSZ;
			B_STATUS (c->rdesc[c->rn]) = 0;
			c->rn = (c->rn + 1) % NBUF;
		}
		outw (c->RX.EDA, (unsigned short) c->rdphys[(i+NBUF-1)%NBUF]);
		/* Clear DMA interrupt. */
		if (inb (c->RX.DSR) & DSR_DMA_ENABLE) {
			outb (c->RX.DSR, dsr);
		} else {
			outb (c->RX.DSR, (dsr & 0xfc) | DSR_DMA_ENABLE);
		}
		++c->rintr;
		break;

	case IMVR_RX_INT:		/* receive status */
		st1 = inb (c->ST1);
		st2 = inb (c->ST2);
		if (st1 & ST1_CDCD){
			if (c->call_on_msig)
				c->call_on_msig (c);
			++c->mintr;
		}
		/* Clear interrupt. */
		outb (c->ST1, st1);
		outb (c->ST2, st2);
		++c->rintr;
		break;

	case IMVR_RX_DMERR:		/* receive DMA error */
		dsr = inb (c->RX.DSR);
		if (dsr & (DSR_CHAIN_BOF | DSR_CHAIN_COF)) {
			if (c->call_on_err)
				c->call_on_err (c, CT_OVERFLOW);
			++c->ierrs;
			for (i=0; i<NBUF; ++i) {
				B_LEN (c->rdesc[i]) = DMABUFSZ;
				B_STATUS (c->rdesc[i]) = 0;
			}
			ct_start_receiver (c, 1, c->rphys[0], DMABUFSZ,
				c->rdphys[0], c->rdphys[NBUF-1]);
			c->rn = 0;
		}
		/* Clear DMA interrupt. */
		outb (c->RX.DSR, dsr);
		++c->rintr;
		break;

	case IMVR_TX_DMOK:		/* transmit DMA normal end */
	case IMVR_TX_DMERR:		/* transmit DMA error	   */
		dsr = inb (c->TX.DSR);
		cda = inw (c->TX.CDA);

		for (i=0; i<NBUF && cda != (unsigned short)c->tdphys[i]; ++i)
			continue;
		if (i >= NBUF)
			i = 1; /* cannot happen */
		if (dsr & DSR_CHAIN_COF) {
			if (c->call_on_err)
				c->call_on_err (c, CT_UNDERRUN);
			++c->oerrs;
		}
		while (c->tn != i) {
			if (c->call_on_tx)
				c->call_on_tx (c, c->attach[c->tn],
					B_LEN(c->tdesc[c->tn]));
			++c->opkts;
			c->obytes += B_LEN(c->tdesc[c->tn]);

			c->tn = (c->tn + 1) % NBUF;
			/* Clear DMA interrupt. */
			outb (c->TX.DSR, DSR_CHAIN_EOM | DSR_DMA_CONTINUE);
		}
		outb (c->TX.DSR, dsr & ~DSR_CHAIN_EOM);
		++c->tintr;
		break;

	case IMVR_TX_INT:		/* transmit error, HDLC only */
		st1 = inb (c->ST1);
		if (st1 & ST1_HDLC_UDRN) {
			if (c->call_on_err)
				c->call_on_err (c, CT_UNDERRUN);
			++c->oerrs;
		}
		outb (c->ST1, st1);
		++c->tintr;
		break;

	default:
		/* Unknown interrupt - cannot happen. */
		break;
	}
}
Пример #12
0
/*
 * Start HDLC channel.
 */
void ct_start_chan (ct_chan_t *c, ct_buf_t *cb, unsigned long phys)
{
	int i, ier0;
	unsigned long bound;

	if (cb) {
		/* Set up descriptors, align to 64k boundary.
		 * If 64k boundary is inside buffers
		 * buffers will begin on this boundary
		 * (there were allocated additional space for this) */
		c->tdesc = cb->descbuf;
		c->tdphys[0] = phys + ((char*)c->tdesc - (char*)cb);
		bound = ((c->tdphys[0] + 0xffff) & ~(0xffffUL));
		if (bound < c->tdphys[0] + 2*NBUF*sizeof(ct_desc_t)) {
			c->tdesc = (ct_desc_t*) ((char*) c->tdesc +
				(bound - c->tdphys[0]));
			c->tdphys[0] = bound;
		}
		c->rdesc = c->tdesc + NBUF;

		/* Set buffers. */
		for (i=0; i<NBUF; ++i) {
			c->rbuf[i] = cb->rbuffer[i];
			c->tbuf[i] = cb->tbuffer[i];
		}

		/* Set buffer physical addresses */
		for (i=0; i<NBUF; ++i) {
			c->rphys[i] = phys + ((char*)c->rbuf[i] - (char*)cb);
			c->tphys[i] = phys + ((char*)c->tbuf[i] - (char*)cb);
			c->rdphys[i] = phys + ((char*)(c->rdesc+i) - (char*)cb);
			c->tdphys[i] = phys + ((char*)(c->tdesc+i) - (char*)cb);
		}
	}
	/* Set up block chains. */
	/* receive buffers */
	for (i=0; i<NBUF; ++i) {
		B_NEXT (c->rdesc[i]) = c->rdphys[(i+1) % NBUF] & 0xffff;
		B_PTR (c->rdesc[i]) = c->rphys[i];
		B_LEN (c->rdesc[i]) = DMABUFSZ;
		B_STATUS (c->rdesc[i]) = 0;
	}
	/* transmit buffers */
	for (i=0; i<NBUF; ++i) {
		B_NEXT (c->tdesc[i]) = c->tdphys[(i+1) % NBUF] & 0xffff;
		B_PTR (c->tdesc[i]) = c->tphys[i];
		B_LEN (c->tdesc[i]) = DMABUFSZ;
		B_STATUS (c->tdesc[i]) = FST_EOM;
		c->attach[i] = 0;
	}

	if (c->type & T_E1) {
		c->mode = M_E1;
		if (c->num && c->board->opt.cfg == CFG_B)
			c->mode = M_HDLC;
	}
	if (c->type & T_G703) {
		c->mode = M_G703;
		if (c->num && c->board->opt.cfg == CFG_B)
			c->mode = M_HDLC;
	}
	ct_update_chan (c);

	/* enable receiver */
	c->rn = 0;
	ct_start_receiver (c, 1 , c->rphys[0], DMABUFSZ, c->rdphys[0],
		c->rdphys[NBUF-1]);
	outb (c->IE1, inb (c->IE1) | IE1_CDCDE);
	outb (c->IE0, inb (c->IE0) | IE0_RX_INTE);
	ier0 = inb (IER0(c->board->port));
	ier0 |= c->num ? IER0_RX_INTE_1 : IER0_RX_INTE_0;
	outb (IER0(c->board->port), ier0);

	/* Enable transmitter */
	c->tn = 0;
	c->te = 0;
	ct_start_transmitter (c, 1 , c->tphys[0], DMABUFSZ, c->tdphys[0],
		c->tdphys[0]);
	outb (c->TX.DIR, DIR_CHAIN_EOME | DIR_CHAIN_BOFE | DIR_CHAIN_COFE);

	/* Clear DTR and RTS */
	ct_set_dtr (c, 0);
	ct_set_rts (c, 0);
}