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); }
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); }