static int safe_prepare_write_buffer(struct usb_serial_port *port,
						void *dest, size_t size)
{
	unsigned char *buf = dest;
	int count;
	int trailer_len;
	int pkt_len;
	__u16 fcs;

	trailer_len = safe ? 2 : 0;

	count = kfifo_out_locked(&port->write_fifo, buf, size - trailer_len,
								&port->lock);
	if (!safe)
		return count;

	/* pad if necessary */
	if (padded) {
		pkt_len = size;
		memset(buf + count, '0', pkt_len - count - trailer_len);
	} else {
		pkt_len = count + trailer_len;
	}

	/* set count */
	buf[pkt_len - 2] = count << 2;
	buf[pkt_len - 1] = 0;

	/* compute fcs and insert into trailer */
	fcs = fcs_compute10(buf, pkt_len, CRC10_INITFCS);
	buf[pkt_len - 2] |= fcs >> 8;
	buf[pkt_len - 1] |= fcs & 0xff;

	return pkt_len;
}
Exemple #2
0
static void safe_process_read_urb(struct urb *urb)
{
	struct usb_serial_port *port = urb->context;
	unsigned char *data = urb->transfer_buffer;
	unsigned char length = urb->actual_length;
	int actual_length;
	__u16 fcs;

	if (!length)
		return;

	if (!safe)
		goto out;

	fcs = fcs_compute10(data, length, CRC10_INITFCS);
	if (fcs) {
		dev_err(&port->dev, "%s - bad CRC %x\n", __func__, fcs);
		return;
	}

	actual_length = data[length - 2] >> 2;
	if (actual_length > (length - 2)) {
		dev_err(&port->dev, "%s - inconsistent lengths %d:%d\n",
				__func__, actual_length, length);
		return;
	}
	dev_info(&urb->dev->dev, "%s - actual: %d\n", __func__, actual_length);
	length = actual_length;
out:
	tty_insert_flip_string(&port->port, data, length);
	tty_flip_buffer_push(&port->port);
}
Exemple #3
0
static void safe_read_bulk_callback (struct urb *urb)
{
	struct usb_serial_port *port = (struct usb_serial_port *) urb->context;
	unsigned char *data = urb->transfer_buffer;
	unsigned char length = urb->actual_length;
	int i;
	int result;
	int status = urb->status;

	dbg ("%s", __FUNCTION__);

	if (status) {
		dbg("%s - nonzero read bulk status received: %d",
		    __FUNCTION__, status);
		return;
	}

	dbg ("safe_read_bulk_callback length: %d", port->read_urb->actual_length);
#ifdef ECHO_RCV
	{
		int i;
		unsigned char *cp = port->read_urb->transfer_buffer;
		for (i = 0; i < port->read_urb->actual_length; i++) {
			if ((i % 32) == 0) {
				printk ("\nru[%02x] ", i);
			}
			printk ("%02x ", *cp++);
		}
		printk ("\n");
	}
#endif
	if (safe) {
		__u16 fcs;
		if (!(fcs = fcs_compute10 (data, length, CRC10_INITFCS))) {

			int actual_length = data[length - 2] >> 2;

			if (actual_length <= (length - 2)) {

				info ("%s - actual: %d", __FUNCTION__, actual_length);

				for (i = 0; i < actual_length; i++) {
					tty_insert_flip_char (port->tty, data[i], 0);
				}
				tty_flip_buffer_push (port->tty);
			} else {
				err ("%s - inconsistent lengths %d:%d", __FUNCTION__,
				     actual_length, length);
			}
		} else {