static void aircable_read(struct work_struct *work)
{
	struct aircable_private *priv =
		container_of(work, struct aircable_private, rx_work);
	struct usb_serial_port *port = priv->port;
	struct tty_struct *tty;
	unsigned char *data;
	int count;
	if (priv->rx_flags & THROTTLED) {
		if (priv->rx_flags & ACTUALLY_THROTTLED)
			schedule_work(&priv->rx_work);
		return;
	}

	/* By now I will flush data to the tty in packages of no more than
	 * 64 bytes, to ensure I do not get throttled.
	 * Ask USB mailing list for better aproach.
	 */
	tty = tty_port_tty_get(&port->port);

	if (!tty) {
		schedule_work(&priv->rx_work);
		dev_err(&port->dev, "%s - No tty available\n", __func__);
		return ;
	}

	count = min(64, serial_buf_data_avail(priv->rx_buf));

	if (count <= 0)
		goto out; /* We have finished sending everything. */

	tty_prepare_flip_string(tty, &data, count);
	if (!data) {
		dev_err(&port->dev, "%s- kzalloc(%d) failed.",
							__func__, count);
		goto out;
	}

	serial_buf_get(priv->rx_buf, data, count);

	tty_flip_buffer_push(tty);

	if (serial_buf_data_avail(priv->rx_buf))
		schedule_work(&priv->rx_work);
out:		
	tty_kref_put(tty);
	return;
}
static void aircable_send(struct usb_serial_port *port)
{
	int count, result;
	struct aircable_private *priv = usb_get_serial_port_data(port);
	unsigned char *buf;
	__le16 *dbuf;
	dbg("%s - port %d", __func__, port->number);
	if (port->write_urb_busy)
		return;

	count = min(serial_buf_data_avail(priv->tx_buf), MAX_HCI_FRAMESIZE);
	if (count == 0)
		return;

	buf = kzalloc(count + HCI_HEADER_LENGTH, GFP_ATOMIC);
	if (!buf) {
		dev_err(&port->dev, "%s- kzalloc(%d) failed.\n",
			__func__, count + HCI_HEADER_LENGTH);
		return;
	}

	buf[0] = TX_HEADER_0;
	buf[1] = TX_HEADER_1;
	dbuf = (__le16 *)&buf[2];
	*dbuf = cpu_to_le16((u16)count);
	serial_buf_get(priv->tx_buf, buf + HCI_HEADER_LENGTH,
							MAX_HCI_FRAMESIZE);

	memcpy(port->write_urb->transfer_buffer, buf,
	       count + HCI_HEADER_LENGTH);

	kfree(buf);
	port->write_urb_busy = 1;
	usb_serial_debug_data(debug, &port->dev, __func__,
			      count + HCI_HEADER_LENGTH,
			      port->write_urb->transfer_buffer);
	port->write_urb->transfer_buffer_length = count + HCI_HEADER_LENGTH;
	port->write_urb->dev = port->serial->dev;
	result = usb_submit_urb(port->write_urb, GFP_ATOMIC);

	if (result) {
		dev_err(&port->dev,
			"%s - failed submitting write urb, error %d\n",
			__func__, result);
		port->write_urb_busy = 0;
	}

	schedule_work(&port->work);
}
Beispiel #3
0
static int aircable_write_room(struct usb_serial_port *port)
{
	struct aircable_private *priv = usb_get_serial_port_data(port);
	return serial_buf_data_avail(priv->tx_buf);
}