/* nci_uart_tty_open * *CalledwhenlinedisciplinechangedtoNCI_UART. * *Arguments: *ttypointertottyinfostructure *ReturnValue: *0ifsuccess,otherwiseerrorcode
*/ staticint nci_uart_tty_open(struct tty_struct *tty)
{ /* Error if the tty has no write op instead of leaving an exploitable *hole
*/ if (!tty->ops->write) return -EOPNOTSUPP;
tty->disc_data = NULL;
tty->receive_room = 65536;
/* Flush any pending characters in the driver */
tty_driver_flush_buffer(tty);
if (!nu->ndev) {
nfc_err(nu->tty->dev, "receive data from tty but no NCI dev is attached yet, drop buffer\n"); return0;
}
/* Decode all incoming data in packets *andenqueuethenforprocessing.
*/ while (count > 0) { /* If this is the first data of a packet, allocate a buffer */ if (!nu->rx_skb) {
nu->rx_packet_len = -1;
nu->rx_skb = nci_skb_alloc(nu->ndev,
NCI_MAX_PACKET_SIZE,
GFP_ATOMIC); if (!nu->rx_skb) return -ENOMEM;
}
/* Eat byte after byte till full packet header is received */ if (nu->rx_skb->len < NCI_CTRL_HDR_SIZE) {
skb_put_u8(nu->rx_skb, *data++);
--count; continue;
}
/* Header was received but packet len was not read */ if (nu->rx_packet_len < 0)
nu->rx_packet_len = NCI_CTRL_HDR_SIZE +
nci_plen(nu->rx_skb->data);
/* Compute how many bytes are missing and how many bytes can *beconsumed.
*/
chunk_len = nu->rx_packet_len - nu->rx_skb->len; if (count < chunk_len)
chunk_len = count;
skb_put_data(nu->rx_skb, data, chunk_len);
data += chunk_len;
count -= chunk_len;
/* Check if packet is fully received */ if (nu->rx_packet_len == nu->rx_skb->len) { /* Pass RX packet to driver */ if (nu->ops.recv(nu, nu->rx_skb) != 0)
nfc_err(nu->tty->dev, "corrupted RX packet\n"); /* Next packet will be a new one */
nu->rx_skb = NULL;
}
}
/* Try to start TX (if possible) */
nci_uart_tx_wakeup(nu);
return0;
}
int nci_uart_register(struct nci_uart *nu)
{ if (!nu || !nu->ops.open ||
!nu->ops.recv || !nu->ops.close) return -EINVAL;
/* Set the send callback */
nu->ops.send = nci_uart_send;
/* Add this driver in the driver list */ if (nci_uart_drivers[nu->driver]) {
pr_err("driver %d is already registered\n", nu->driver); return -EBUSY;
}
nci_uart_drivers[nu->driver] = nu;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.