static void isac_fill_fifo(struct isac *isac)
{
	// this also works for isacsx, since
	// CMDR(D) register works the same

	int count;
	unsigned char cmd;
	u_char *ptr;

	BUG_ON(!isac->tx_skb);

	count = isac->tx_skb->len;
	BUG_ON(count <= 0);

	DBG(DBG_IRQ, "count %d", count);

	if (count > 0x20) {
		count = 0x20;
		cmd = ISAC_CMDR_XTF;
	} else {
		cmd = ISAC_CMDR_XTF | ISAC_CMDR_XME;
	}

	ptr = isac->tx_skb->data;
	skb_pull(isac->tx_skb, count);
	isac->tx_cnt += count;
	DBG_PACKET(DBG_XFIFO, ptr, count);
	isac->write_isac_fifo(isac, ptr, count);
	isac->write_isac(isac, ISAC_CMDR, cmd);
}
Пример #2
0
/*
 * Decode frames received on the B/D channel.
 * Note that this function will be called continously
 * with 64Kbit/s / 16Kbit/s of data and hence it will be 
 * called 50 times per second with 20 ISOC descriptors. 
 * Called at interrupt.
 */
static void usb_in_complete(struct urb *urb)
{
	struct st5481_in *in = urb->context;
	unsigned char *ptr;
	struct sk_buff *skb;
	int len, count, status;

	if (urb->status < 0) {
		if (urb->status != USB_ST_URB_KILLED) {
			WARN("urb status %d",urb->status);
		} else {
			DBG(1,"urb killed");
			return; // Give up
		}
	}

	DBG_ISO_PACKET(0x80,urb);

	len = st5481_isoc_flatten(urb);
	ptr = urb->transfer_buffer;
	while (len > 0) {
		if (in->mode == L1_MODE_TRANS) {
			/* swap rx bytes to get hearable audio */
			register unsigned char *dest = in->rcvbuf;
			status = len;
			for (; len; len--)
				*dest++ = isdnhdlc_bit_rev_tab[*ptr++];
		} else {
			status = isdnhdlc_decode(&in->hdlc_state, ptr, len, &count,
					         in->rcvbuf, in->bufsize);
			ptr += count;
			len -= count;
		}

		if (status > 0) {
			// Good frame received
			DBG(4,"count=%d",status);
			DBG_PACKET(0x400, in->rcvbuf, status);
			if (!(skb = dev_alloc_skb(status))) {
				WARN("receive out of memory\n");
				break;
			}
			memcpy(skb_put(skb, status), in->rcvbuf, status);
			in->hisax_if->l1l2(in->hisax_if, PH_DATA | INDICATION, skb);
		} else if (status == -HDLC_CRC_ERROR) {
			INFO("CRC error");
		} else if (status == -HDLC_FRAMING_ERROR) {
			INFO("framing error");
		} else if (status == -HDLC_LENGTH_ERROR) {
			INFO("length error");
		}
	}

	// Prepare URB for next transfer
	urb->dev = in->adapter->usb_dev;
	urb->actual_length = 0;

	SUBMIT_URB(urb);
}
static void usb_int_complete(struct urb *urb)
{
	u8 *data = urb->transfer_buffer;
	u8 irqbyte;
	struct st5481_adapter *adapter = urb->context;
	int j;
	int status;

	switch (urb->status) {
	case 0:
		
		break;
	case -ECONNRESET:
	case -ENOENT:
	case -ESHUTDOWN:
		
		DBG(2, "urb shutting down with status: %d", urb->status);
		return;
	default:
		WARNING("nonzero urb status received: %d", urb->status);
		goto exit;
	}


	DBG_PACKET(2, data, INT_PKT_SIZE);

	if (urb->actual_length == 0) {
		goto exit;
	}

	irqbyte = data[MPINT];
	if (irqbyte & DEN_INT)
		FsmEvent(&adapter->d_out.fsm, EV_DOUT_DEN, NULL);

	if (irqbyte & DCOLL_INT)
		FsmEvent(&adapter->d_out.fsm, EV_DOUT_COLL, NULL);

	irqbyte = data[FFINT_D];
	if (irqbyte & OUT_UNDERRUN)
		FsmEvent(&adapter->d_out.fsm, EV_DOUT_UNDERRUN, NULL);

	if (irqbyte & OUT_DOWN)
		;

	irqbyte = data[MPINT];
	if (irqbyte & RXCI_INT)
		FsmEvent(&adapter->l1m, data[CCIST] & 0x0f, NULL);

	for (j = 0; j < 2; j++)
		adapter->bcs[j].b_out.flow_event |= data[FFINT_B1 + j];

	urb->actual_length = 0;

exit:
	status = usb_submit_urb(urb, GFP_ATOMIC);
	if (status)
		WARNING("usb_submit_urb failed with result %d", status);
}
Пример #4
0
STATIC VOID recvproc(INT iRcvFd, INT iSndFd)
{
    INT iRet = 0;
    CHAR acBuf[MAX_BUF_2048];
    CHAR acBufIP[MAX_BUF_128];
    INT iReplayAddrLen = 0;
    struct sockaddr_in stReplyAddr;
    struct sockaddr_in stDstAddr;
    STATIC ULONG g_ulSndCnt = 0;

    memset((CHAR*) &(stDstAddr),0, sizeof((stDstAddr)));
    stDstAddr.sin_family = AF_INET;
    stDstAddr.sin_addr.s_addr = inet_addr(g_acDestionIP);
    stDstAddr.sin_port = htons(g_usDestionPort);

    iReplayAddrLen = sizeof(stReplyAddr);
    memset(&stReplyAddr, 0 , sizeof(stReplyAddr));

    do
    {
        iRet = recvfrom(iRcvFd, acBuf, sizeof(acBuf) - 1, 0, (struct sockaddr *)&stReplyAddr, &iReplayAddrLen);
    } while ((0 > iRet) && (errno == EINTR));

    if (0 >= iRet)
    {
        DBG_ERROR("Receive message failed, fd %d, error:%s.\n", iRcvFd, strerror(errno));
        return;
    }

    if (inet_addr(g_acLocalIP) == stReplyAddr.sin_addr.s_addr)
    {
        DBG_ERROR("Drop message received on local(%s:%hu)\n", inet_ntoa(stReplyAddr.sin_addr), ntohs(stReplyAddr.sin_port));
        return;
    }

    strlcpy(acBufIP, inet_ntoa(stDstAddr.sin_addr), sizeof(acBufIP));
    DBG_PACKET("%lu:Send %d length message to %s:%hu from %s:%hu\n", g_ulSndCnt++, iRet,
               acBufIP, ntohs(stDstAddr.sin_port),
               inet_ntoa(stReplyAddr.sin_addr), ntohs(stReplyAddr.sin_port));
    do
    {
        iRet = sendto(iSndFd, acBuf, iRet, 0, (struct sockaddr *)&stDstAddr, sizeof(struct sockaddr_in));
    } while ((0 > iRet) && (errno == EINTR));

    if (0 > iRet)
    {
        DBG_ERROR("Faild to send packet to %s, error:%s\n", inet_ntoa(stDstAddr.sin_addr), strerror(errno));
        return;
    }

    return;
}
Пример #5
0
/*
 * The interrupt endpoint will be called when any
 * of the 6 registers changes state (depending on masks).
 * Decode the register values and schedule a private event.
 * Called at interrupt.
 */
static void usb_int_complete(struct urb *urb)
{
	u_char *data = urb->transfer_buffer;
	u_char irqbyte;
	struct st5481_adapter *adapter = urb->context;
	int j;

	if (urb->status < 0) {
		if (urb->status != -ENOENT) {
			WARN("urb status %d",urb->status);
			urb->actual_length = 0;
		} else {
			DBG(1,"urb killed");
			return; // Give up
		}
	}
	
	DBG_PACKET(1, data, INT_PKT_SIZE);
		
	if (urb->actual_length == 0) {
		return;
	}

	irqbyte = data[MPINT];
	if (irqbyte & DEN_INT)
		FsmEvent(&adapter->d_out.fsm, EV_DOUT_DEN, NULL);

	if (irqbyte & DCOLL_INT)
		FsmEvent(&adapter->d_out.fsm, EV_DOUT_COLL, NULL);

	irqbyte = data[FFINT_D];
	if (irqbyte & OUT_UNDERRUN)
		FsmEvent(&adapter->d_out.fsm, EV_DOUT_UNDERRUN, NULL);

	if (irqbyte & OUT_DOWN)
;//		printk("OUT_DOWN\n");

	irqbyte = data[MPINT];
	if (irqbyte & RXCI_INT)
		FsmEvent(&adapter->l1m, data[CCIST] & 0x0f, NULL);

	for (j = 0; j < 2; j++)
		adapter->bcs[j].b_out.flow_event |= data[FFINT_B1 + j];

	urb->actual_length = 0;
}
static void isac_empty_fifo(struct isac *isac, int count)
{
	// this also works for isacsx, since
	// CMDR(D) register works the same
	u_char *ptr;

	DBG(DBG_IRQ, "count %d", count);

	if ((isac->rcvidx + count) >= MAX_DFRAME_LEN_L1) {
		DBG(DBG_WARN, "overrun %d", isac->rcvidx + count);
		isac->write_isac(isac, ISAC_CMDR, ISAC_CMDR_RMC);
		isac->rcvidx = 0;
		return;
	}
	ptr = isac->rcvbuf + isac->rcvidx;
	isac->rcvidx += count;
	isac->read_isac_fifo(isac, ptr, count);
	isac->write_isac(isac, ISAC_CMDR, ISAC_CMDR_RMC);
	DBG_PACKET(DBG_RFIFO, ptr, count);
}
Пример #7
0
static void
rx_iso_complete(struct urb *urb)
{
	iso_urb_struct *context_iso_urb = (iso_urb_struct *) urb->context;
	usb_fifo *fifo = context_iso_urb->owner_fifo;
	hfcusb_data *hfc = fifo->hfc;
	int k, len, errcode, offset, num_isoc_packets, fifon, maxlen,
		status;
	unsigned int iso_status;
	__u8 *buf;
	static __u8 eof[8];

	fifon = fifo->fifonum;
	status = urb->status;

	if (urb->status == -EOVERFLOW) {
		DBG(HFCUSB_DBG_VERBOSE_USB,
		    "HFC-USB: ignoring USB DATAOVERRUN fifo(%i)", fifon);
		status = 0;
	}

	/* ISO transfer only partially completed,
	   look at individual frame status for details */
	if (status == -EXDEV) {
		DBG(HFCUSB_DBG_VERBOSE_USB, "HFC-S USB: rx_iso_complete with -EXDEV "
		    "urb->status %d, fifonum %d\n",
		    status, fifon);
		status = 0;
	}

	if (fifo->active && !status) {
		num_isoc_packets = iso_packets[fifon];
		maxlen = fifo->usb_packet_maxlen;
		for (k = 0; k < num_isoc_packets; ++k) {
			len = urb->iso_frame_desc[k].actual_length;
			offset = urb->iso_frame_desc[k].offset;
			buf = context_iso_urb->buffer + offset;
			iso_status = urb->iso_frame_desc[k].status;

			if (iso_status && !hfc->disc_flag)
				DBG(HFCUSB_DBG_VERBOSE_USB,
				    "HFC-S USB: rx_iso_complete "
				    "ISO packet %i, status: %i\n",
				    k, iso_status);

			if (fifon == HFCUSB_D_RX) {
				DBG(HFCUSB_DBG_VERBOSE_USB,
				    "HFC-S USB: ISO-D-RX lst_urblen:%2d "
				    "act_urblen:%2d max-urblen:%2d EOF:0x%0x",
				    fifo->last_urblen, len, maxlen,
				    eof[5]);

				DBG_PACKET(HFCUSB_DBG_VERBOSE_USB, buf, len);
			}

			if (fifo->last_urblen != maxlen) {
				/* the threshold mask is in the 2nd status byte */
				hfc->threshold_mask = buf[1];
				/* care for L1 state only for D-Channel
				   to avoid overlapped iso completions */
				if (fifon == HFCUSB_D_RX) {
					/* the S0 state is in the upper half
					   of the 1st status byte */
					s0_state_handler(hfc, buf[0] >> 4);
				}
				eof[fifon] = buf[0] & 1;
				if (len > 2)
					collect_rx_frame(fifo, buf + 2,
							 len - 2,
							 (len < maxlen) ?
							 eof[fifon] : 0);
			} else {
static void usb_in_complete(struct urb *urb)
{
	struct st5481_in *in = urb->context;
	unsigned char *ptr;
	struct sk_buff *skb;
	int len, count, status;

	if (unlikely(urb->status < 0)) {
		switch (urb->status) {
		case -ENOENT:
		case -ESHUTDOWN:
		case -ECONNRESET:
			DBG(1, "urb killed status %d", urb->status);
			return; 
		default:
			WARNING("urb status %d", urb->status);
			break;
		}
	}

	DBG_ISO_PACKET(0x80, urb);

	len = st5481_isoc_flatten(urb);
	ptr = urb->transfer_buffer;
	while (len > 0) {
		if (in->mode == L1_MODE_TRANS) {
			memcpy(in->rcvbuf, ptr, len);
			status = len;
			len = 0;
		} else {
			status = isdnhdlc_decode(&in->hdlc_state, ptr, len, &count,
						 in->rcvbuf, in->bufsize);
			ptr += count;
			len -= count;
		}

		if (status > 0) {
			
			DBG(4, "count=%d", status);
			DBG_PACKET(0x400, in->rcvbuf, status);
			if (!(skb = dev_alloc_skb(status))) {
				WARNING("receive out of memory\n");
				break;
			}
			memcpy(skb_put(skb, status), in->rcvbuf, status);
			in->hisax_if->l1l2(in->hisax_if, PH_DATA | INDICATION, skb);
		} else if (status == -HDLC_CRC_ERROR) {
			INFO("CRC error");
		} else if (status == -HDLC_FRAMING_ERROR) {
			INFO("framing error");
		} else if (status == -HDLC_LENGTH_ERROR) {
			INFO("length error");
		}
	}

	
	urb->dev = in->adapter->usb_dev;
	urb->actual_length = 0;

	SUBMIT_URB(urb, GFP_ATOMIC);
}