Skip to content

Commit

Permalink
tty: make receive_buf() return the amout of bytes received
Browse files Browse the repository at this point in the history
it makes it simpler to keep track of the amount of
bytes received and simplifies how flush_to_ldisc counts
the remaining bytes. It also fixes a bug of lost bytes
on n_tty when flushing too many bytes via the USB
serial gadget driver.

Tested-by: Stefan Bigler <stefan.bigler@keymile.com>
Tested-by: Toby Gray <toby.gray@realvnc.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
  • Loading branch information
Felipe Balbi authored and Greg Kroah-Hartman committed Apr 23, 2011
1 parent e9a470f commit b1c43f8
Show file tree
Hide file tree
Showing 20 changed files with 125 additions and 113 deletions.
12 changes: 8 additions & 4 deletions drivers/bluetooth/hci_ldisc.c
Original file line number Diff line number Diff line change
Expand Up @@ -357,22 +357,26 @@ static void hci_uart_tty_wakeup(struct tty_struct *tty)
*
* Return Value: None
*/
static void hci_uart_tty_receive(struct tty_struct *tty, const u8 *data, char *flags, int count)
static unsigned int hci_uart_tty_receive(struct tty_struct *tty,
const u8 *data, char *flags, int count)
{
struct hci_uart *hu = (void *)tty->disc_data;
int received;

if (!hu || tty != hu->tty)
return;
return -ENODEV;

if (!test_bit(HCI_UART_PROTO_SET, &hu->flags))
return;
return -EINVAL;

spin_lock(&hu->rx_lock);
hu->proto->recv(hu, (void *) data, count);
received = hu->proto->recv(hu, (void *) data, count);
hu->hdev->stat.byte_rx += count;
spin_unlock(&hu->rx_lock);

tty_unthrottle(tty);

return received;
}

static int hci_uart_register_dev(struct hci_uart *hu)
Expand Down
10 changes: 8 additions & 2 deletions drivers/input/serio/serport.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,17 +120,21 @@ static void serport_ldisc_close(struct tty_struct *tty)
* 'interrupt' routine.
*/

static void serport_ldisc_receive(struct tty_struct *tty, const unsigned char *cp, char *fp, int count)
static unsigned int serport_ldisc_receive(struct tty_struct *tty,
const unsigned char *cp, char *fp, int count)
{
struct serport *serport = (struct serport*) tty->disc_data;
unsigned long flags;
unsigned int ch_flags;
int ret = 0;
int i;

spin_lock_irqsave(&serport->lock, flags);

if (!test_bit(SERPORT_ACTIVE, &serport->flags))
if (!test_bit(SERPORT_ACTIVE, &serport->flags)) {
ret = -EINVAL;
goto out;
}

for (i = 0; i < count; i++) {
switch (fp[i]) {
Expand All @@ -152,6 +156,8 @@ static void serport_ldisc_receive(struct tty_struct *tty, const unsigned char *c

out:
spin_unlock_irqrestore(&serport->lock, flags);

return ret == 0 ? count : ret;
}

/*
Expand Down
8 changes: 5 additions & 3 deletions drivers/isdn/gigaset/ser-gigaset.c
Original file line number Diff line number Diff line change
Expand Up @@ -674,7 +674,7 @@ gigaset_tty_ioctl(struct tty_struct *tty, struct file *file,
* cflags buffer containing error flags for received characters (ignored)
* count number of received characters
*/
static void
static unsigned int
gigaset_tty_receive(struct tty_struct *tty, const unsigned char *buf,
char *cflags, int count)
{
Expand All @@ -683,12 +683,12 @@ gigaset_tty_receive(struct tty_struct *tty, const unsigned char *buf,
struct inbuf_t *inbuf;

if (!cs)
return;
return -ENODEV;
inbuf = cs->inbuf;
if (!inbuf) {
dev_err(cs->dev, "%s: no inbuf\n", __func__);
cs_put(cs);
return;
return -EINVAL;
}

tail = inbuf->tail;
Expand Down Expand Up @@ -725,6 +725,8 @@ gigaset_tty_receive(struct tty_struct *tty, const unsigned char *buf,
gig_dbg(DEBUG_INTR, "%s-->BH", __func__);
gigaset_schedule_event(cs);
cs_put(cs);

return count;
}

/*
Expand Down
6 changes: 4 additions & 2 deletions drivers/misc/ti-st/st_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -744,8 +744,8 @@ static void st_tty_close(struct tty_struct *tty)
pr_debug("%s: done ", __func__);
}

static void st_tty_receive(struct tty_struct *tty, const unsigned char *data,
char *tty_flags, int count)
static unsigned int st_tty_receive(struct tty_struct *tty,
const unsigned char *data, char *tty_flags, int count)
{
#ifdef VERBOSE
print_hex_dump(KERN_DEBUG, ">in>", DUMP_PREFIX_NONE,
Expand All @@ -758,6 +758,8 @@ static void st_tty_receive(struct tty_struct *tty, const unsigned char *data,
*/
st_recv(tty->disc_data, data, count);
pr_debug("done %s", __func__);

return count;
}

/* wake-up function called in from the TTY layer
Expand Down
6 changes: 4 additions & 2 deletions drivers/net/caif/caif_serial.c
Original file line number Diff line number Diff line change
Expand Up @@ -167,8 +167,8 @@ static inline void debugfs_tx(struct ser_device *ser, const u8 *data, int size)

#endif

static void ldisc_receive(struct tty_struct *tty, const u8 *data,
char *flags, int count)
static unsigned int ldisc_receive(struct tty_struct *tty,
const u8 *data, char *flags, int count)
{
struct sk_buff *skb = NULL;
struct ser_device *ser;
Expand Down Expand Up @@ -215,6 +215,8 @@ static void ldisc_receive(struct tty_struct *tty, const u8 *data,
} else
++ser->dev->stats.rx_dropped;
update_tty_status(ser);

return count;
}

static int handle_tx(struct ser_device *ser)
Expand Down
9 changes: 6 additions & 3 deletions drivers/net/can/slcan.c
Original file line number Diff line number Diff line change
Expand Up @@ -425,16 +425,17 @@ static void slc_setup(struct net_device *dev)
* in parallel
*/

static void slcan_receive_buf(struct tty_struct *tty,
static unsigned int slcan_receive_buf(struct tty_struct *tty,
const unsigned char *cp, char *fp, int count)
{
struct slcan *sl = (struct slcan *) tty->disc_data;
int bytes = count;

if (!sl || sl->magic != SLCAN_MAGIC || !netif_running(sl->dev))
return;
return -ENODEV;

/* Read the characters out of the buffer */
while (count--) {
while (bytes--) {
if (fp && *fp++) {
if (!test_and_set_bit(SLF_ERROR, &sl->flags))
sl->dev->stats.rx_errors++;
Expand All @@ -443,6 +444,8 @@ static void slcan_receive_buf(struct tty_struct *tty,
}
slcan_unesc(sl, *cp++);
}

return count;
}

/************************************
Expand Down
8 changes: 5 additions & 3 deletions drivers/net/hamradio/6pack.c
Original file line number Diff line number Diff line change
Expand Up @@ -456,19 +456,19 @@ static void sixpack_write_wakeup(struct tty_struct *tty)
* a block of 6pack data has been received, which can now be decapsulated
* and sent on to some IP layer for further processing.
*/
static void sixpack_receive_buf(struct tty_struct *tty,
static unsigned int sixpack_receive_buf(struct tty_struct *tty,
const unsigned char *cp, char *fp, int count)
{
struct sixpack *sp;
unsigned char buf[512];
int count1;

if (!count)
return;
return 0;

sp = sp_get(tty);
if (!sp)
return;
return -ENODEV;

memcpy(buf, cp, count < sizeof(buf) ? count : sizeof(buf));

Expand All @@ -487,6 +487,8 @@ static void sixpack_receive_buf(struct tty_struct *tty,

sp_put(sp);
tty_unthrottle(tty);

return count1;
}

/*
Expand Down
11 changes: 7 additions & 4 deletions drivers/net/hamradio/mkiss.c
Original file line number Diff line number Diff line change
Expand Up @@ -923,13 +923,14 @@ static long mkiss_compat_ioctl(struct tty_struct *tty, struct file *file,
* a block of data has been received, which can now be decapsulated
* and sent on to the AX.25 layer for further processing.
*/
static void mkiss_receive_buf(struct tty_struct *tty, const unsigned char *cp,
char *fp, int count)
static unsigned int mkiss_receive_buf(struct tty_struct *tty,
const unsigned char *cp, char *fp, int count)
{
struct mkiss *ax = mkiss_get(tty);
int bytes = count;

if (!ax)
return;
return -ENODEV;

/*
* Argh! mtu change time! - costs us the packet part received
Expand All @@ -939,7 +940,7 @@ static void mkiss_receive_buf(struct tty_struct *tty, const unsigned char *cp,
ax_changedmtu(ax);

/* Read the characters out of the buffer */
while (count--) {
while (bytes--) {
if (fp != NULL && *fp++) {
if (!test_and_set_bit(AXF_ERROR, &ax->flags))
ax->dev->stats.rx_errors++;
Expand All @@ -952,6 +953,8 @@ static void mkiss_receive_buf(struct tty_struct *tty, const unsigned char *cp,

mkiss_put(ax);
tty_unthrottle(tty);

return count;
}

/*
Expand Down
16 changes: 9 additions & 7 deletions drivers/net/irda/irtty-sir.c
Original file line number Diff line number Diff line change
Expand Up @@ -216,23 +216,23 @@ static int irtty_do_write(struct sir_dev *dev, const unsigned char *ptr, size_t
* usbserial: urb-complete-interrupt / softint
*/

static void irtty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
char *fp, int count)
static unsigned int irtty_receive_buf(struct tty_struct *tty,
const unsigned char *cp, char *fp, int count)
{
struct sir_dev *dev;
struct sirtty_cb *priv = tty->disc_data;
int i;

IRDA_ASSERT(priv != NULL, return;);
IRDA_ASSERT(priv->magic == IRTTY_MAGIC, return;);
IRDA_ASSERT(priv != NULL, return -ENODEV;);
IRDA_ASSERT(priv->magic == IRTTY_MAGIC, return -EINVAL;);

if (unlikely(count==0)) /* yes, this happens */
return;
return 0;

dev = priv->dev;
if (!dev) {
IRDA_WARNING("%s(), not ready yet!\n", __func__);
return;
return -ENODEV;
}

for (i = 0; i < count; i++) {
Expand All @@ -242,11 +242,13 @@ static void irtty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
if (fp && *fp++) {
IRDA_DEBUG(0, "Framing or parity error!\n");
sirdev_receive(dev, NULL, 0); /* notify sir_dev (updating stats) */
return;
return -EINVAL;
}
}

sirdev_receive(dev, cp, count);

return count;
}

/*
Expand Down
6 changes: 4 additions & 2 deletions drivers/net/ppp_async.c
Original file line number Diff line number Diff line change
Expand Up @@ -340,22 +340,24 @@ ppp_asynctty_poll(struct tty_struct *tty, struct file *file, poll_table *wait)
}

/* May sleep, don't call from interrupt level or with interrupts disabled */
static void
static unsigned int
ppp_asynctty_receive(struct tty_struct *tty, const unsigned char *buf,
char *cflags, int count)
{
struct asyncppp *ap = ap_get(tty);
unsigned long flags;

if (!ap)
return;
return -ENODEV;
spin_lock_irqsave(&ap->recv_lock, flags);
ppp_async_input(ap, buf, cflags, count);
spin_unlock_irqrestore(&ap->recv_lock, flags);
if (!skb_queue_empty(&ap->rqueue))
tasklet_schedule(&ap->tsk);
ap_put(ap);
tty_unthrottle(tty);

return count;
}

static void
Expand Down
6 changes: 4 additions & 2 deletions drivers/net/ppp_synctty.c
Original file line number Diff line number Diff line change
Expand Up @@ -381,22 +381,24 @@ ppp_sync_poll(struct tty_struct *tty, struct file *file, poll_table *wait)
}

/* May sleep, don't call from interrupt level or with interrupts disabled */
static void
static unsigned int
ppp_sync_receive(struct tty_struct *tty, const unsigned char *buf,
char *cflags, int count)
{
struct syncppp *ap = sp_get(tty);
unsigned long flags;

if (!ap)
return;
return -ENODEV;
spin_lock_irqsave(&ap->recv_lock, flags);
ppp_sync_input(ap, buf, cflags, count);
spin_unlock_irqrestore(&ap->recv_lock, flags);
if (!skb_queue_empty(&ap->rqueue))
tasklet_schedule(&ap->tsk);
sp_put(ap);
tty_unthrottle(tty);

return count;
}

static void
Expand Down
11 changes: 7 additions & 4 deletions drivers/net/slip.c
Original file line number Diff line number Diff line change
Expand Up @@ -670,16 +670,17 @@ static void sl_setup(struct net_device *dev)
* in parallel
*/

static void slip_receive_buf(struct tty_struct *tty, const unsigned char *cp,
char *fp, int count)
static unsigned int slip_receive_buf(struct tty_struct *tty,
const unsigned char *cp, char *fp, int count)
{
struct slip *sl = tty->disc_data;
int bytes = count;

if (!sl || sl->magic != SLIP_MAGIC || !netif_running(sl->dev))
return;
return -ENODEV;

/* Read the characters out of the buffer */
while (count--) {
while (bytes--) {
if (fp && *fp++) {
if (!test_and_set_bit(SLF_ERROR, &sl->flags))
sl->dev->stats.rx_errors++;
Expand All @@ -693,6 +694,8 @@ static void slip_receive_buf(struct tty_struct *tty, const unsigned char *cp,
#endif
slip_unesc(sl, *cp++);
}

return count;
}

/************************************
Expand Down
7 changes: 5 additions & 2 deletions drivers/net/wan/x25_asy.c
Original file line number Diff line number Diff line change
Expand Up @@ -517,17 +517,18 @@ static int x25_asy_close(struct net_device *dev)
* and sent on to some IP layer for further processing.
*/

static void x25_asy_receive_buf(struct tty_struct *tty,
static unsigned int x25_asy_receive_buf(struct tty_struct *tty,
const unsigned char *cp, char *fp, int count)
{
struct x25_asy *sl = tty->disc_data;
int bytes = count;

if (!sl || sl->magic != X25_ASY_MAGIC || !netif_running(sl->dev))
return;


/* Read the characters out of the buffer */
while (count--) {
while (bytes--) {
if (fp && *fp++) {
if (!test_and_set_bit(SLF_ERROR, &sl->flags))
sl->dev->stats.rx_errors++;
Expand All @@ -536,6 +537,8 @@ static void x25_asy_receive_buf(struct tty_struct *tty,
}
x25_asy_unesc(sl, *cp++);
}

return count;
}

/*
Expand Down
Loading

0 comments on commit b1c43f8

Please sign in to comment.