Commit 0fdf7a3ea381e0d12a46883e97af808d959255e9
1 parent
df2832d8
Enable some data flow control according to the unread data buffer of the paired port.
Showing
1 changed file
with
32 additions
and
3 deletions
module/tty0tty.c
| @@ -72,6 +72,8 @@ MODULE_LICENSE("GPL"); | @@ -72,6 +72,8 @@ MODULE_LICENSE("GPL"); | ||
| 72 | #define MSR_DSR 0x40 | 72 | #define MSR_DSR 0x40 |
| 73 | #define MSR_RI 0x80 | 73 | #define MSR_RI 0x80 |
| 74 | 74 | ||
| 75 | +#define WRITE_ROOM_MAX 64 | ||
| 76 | + | ||
| 75 | struct tty0tty_serial { | 77 | struct tty0tty_serial { |
| 76 | struct tty_struct *tty; /* pointer to the tty for this device */ | 78 | struct tty_struct *tty; /* pointer to the tty for this device */ |
| 77 | int open_count; /* number of times this port has been opened */ | 79 | int open_count; /* number of times this port has been opened */ |
| @@ -89,6 +91,8 @@ struct tty0tty_serial { | @@ -89,6 +91,8 @@ struct tty0tty_serial { | ||
| 89 | 91 | ||
| 90 | static struct tty0tty_serial *tty0tty_table[TINY_TTY_MINORS]; /* initially all NULL */ | 92 | static struct tty0tty_serial *tty0tty_table[TINY_TTY_MINORS]; /* initially all NULL */ |
| 91 | 93 | ||
| 94 | +/* Function prototypes */ | ||
| 95 | +static int tty0tty_write_room(struct tty_struct *tty); | ||
| 92 | 96 | ||
| 93 | static inline void null_modem_signal_copy(struct tty0tty_serial * tty_to, const struct tty0tty_serial * tty_from) | 97 | static inline void null_modem_signal_copy(struct tty0tty_serial * tty_to, const struct tty0tty_serial * tty_from) |
| 94 | { | 98 | { |
| @@ -197,6 +201,12 @@ static int tty0tty_write(struct tty_struct *tty, const unsigned char *buffer, in | @@ -197,6 +201,12 @@ static int tty0tty_write(struct tty_struct *tty, const unsigned char *buffer, in | ||
| 197 | int retval = -EINVAL; | 201 | int retval = -EINVAL; |
| 198 | struct tty_struct *ttyx = NULL; | 202 | struct tty_struct *ttyx = NULL; |
| 199 | int paired_index; | 203 | int paired_index; |
| 204 | + int room = 0; | ||
| 205 | + | ||
| 206 | + room = tty0tty_write_room(tty); | ||
| 207 | + if (room < 0) | ||
| 208 | + /* error case */ | ||
| 209 | + return room; | ||
| 200 | 210 | ||
| 201 | if (!tty0tty) | 211 | if (!tty0tty) |
| 202 | return -ENODEV; | 212 | return -ENODEV; |
| @@ -214,12 +224,14 @@ static int tty0tty_write(struct tty_struct *tty, const unsigned char *buffer, in | @@ -214,12 +224,14 @@ static int tty0tty_write(struct tty_struct *tty, const unsigned char *buffer, in | ||
| 214 | 224 | ||
| 215 | // tty->low_latency=1; | 225 | // tty->low_latency=1; |
| 216 | 226 | ||
| 227 | + if (count > room) | ||
| 228 | + count = room; | ||
| 217 | if(ttyx != NULL) | 229 | if(ttyx != NULL) |
| 218 | { | 230 | { |
| 219 | tty_insert_flip_string(ttyx, buffer, count); | 231 | tty_insert_flip_string(ttyx, buffer, count); |
| 220 | tty_flip_buffer_push(ttyx); | 232 | tty_flip_buffer_push(ttyx); |
| 221 | - retval=count; | ||
| 222 | } | 233 | } |
| 234 | + retval=count; | ||
| 223 | 235 | ||
| 224 | exit: | 236 | exit: |
| 225 | up(&tty0tty->sem); | 237 | up(&tty0tty->sem); |
| @@ -229,20 +241,37 @@ exit: | @@ -229,20 +241,37 @@ exit: | ||
| 229 | static int tty0tty_write_room(struct tty_struct *tty) | 241 | static int tty0tty_write_room(struct tty_struct *tty) |
| 230 | { | 242 | { |
| 231 | struct tty0tty_serial *tty0tty = tty->driver_data; | 243 | struct tty0tty_serial *tty0tty = tty->driver_data; |
| 244 | + struct tty0tty_serial *tty0tty_paired = NULL; | ||
| 245 | + int index; | ||
| 246 | + int paired_index; | ||
| 232 | int room = -EINVAL; | 247 | int room = -EINVAL; |
| 233 | 248 | ||
| 234 | if (!tty0tty) | 249 | if (!tty0tty) |
| 235 | return -ENODEV; | 250 | return -ENODEV; |
| 236 | 251 | ||
| 237 | down(&tty0tty->sem); | 252 | down(&tty0tty->sem); |
| 238 | - | 253 | + |
| 239 | if (!tty0tty->open_count) { | 254 | if (!tty0tty->open_count) { |
| 240 | /* port was not opened */ | 255 | /* port was not opened */ |
| 241 | goto exit; | 256 | goto exit; |
| 242 | } | 257 | } |
| 243 | 258 | ||
| 259 | + /* get the serial object associated with this tty pointer */ | ||
| 260 | + index = tty->index; | ||
| 261 | + paired_index = PAIRED_INDEX(index); | ||
| 262 | + tty0tty_paired = tty0tty_table[paired_index]; | ||
| 263 | + if (tty0tty_paired == NULL || tty0tty_paired->open_count == 0) { | ||
| 264 | + /* Paired port is not open */ | ||
| 265 | + /* Effectively dump all written bytes */ | ||
| 266 | + room = WRITE_ROOM_MAX; | ||
| 267 | + goto exit; | ||
| 268 | + } | ||
| 269 | + | ||
| 244 | /* calculate how much room is left in the device */ | 270 | /* calculate how much room is left in the device */ |
| 245 | - room = 255; | 271 | + room = WRITE_ROOM_MAX - tty0tty_paired->tty->read_cnt; |
| 272 | + if (room < 0) { | ||
| 273 | + room = 0; | ||
| 274 | + } | ||
| 246 | 275 | ||
| 247 | exit: | 276 | exit: |
| 248 | up(&tty0tty->sem); | 277 | up(&tty0tty->sem); |