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 | 72 | #define MSR_DSR 0x40 |
| 73 | 73 | #define MSR_RI 0x80 |
| 74 | 74 | |
| 75 | +#define WRITE_ROOM_MAX 64 | |
| 76 | + | |
| 75 | 77 | struct tty0tty_serial { |
| 76 | 78 | struct tty_struct *tty; /* pointer to the tty for this device */ |
| 77 | 79 | int open_count; /* number of times this port has been opened */ |
| ... | ... | @@ -89,6 +91,8 @@ struct tty0tty_serial { |
| 89 | 91 | |
| 90 | 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 | 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 | 201 | int retval = -EINVAL; |
| 198 | 202 | struct tty_struct *ttyx = NULL; |
| 199 | 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 | 211 | if (!tty0tty) |
| 202 | 212 | return -ENODEV; |
| ... | ... | @@ -214,12 +224,14 @@ static int tty0tty_write(struct tty_struct *tty, const unsigned char *buffer, in |
| 214 | 224 | |
| 215 | 225 | // tty->low_latency=1; |
| 216 | 226 | |
| 227 | + if (count > room) | |
| 228 | + count = room; | |
| 217 | 229 | if(ttyx != NULL) |
| 218 | 230 | { |
| 219 | 231 | tty_insert_flip_string(ttyx, buffer, count); |
| 220 | 232 | tty_flip_buffer_push(ttyx); |
| 221 | - retval=count; | |
| 222 | 233 | } |
| 234 | + retval=count; | |
| 223 | 235 | |
| 224 | 236 | exit: |
| 225 | 237 | up(&tty0tty->sem); |
| ... | ... | @@ -229,20 +241,37 @@ exit: |
| 229 | 241 | static int tty0tty_write_room(struct tty_struct *tty) |
| 230 | 242 | { |
| 231 | 243 | struct tty0tty_serial *tty0tty = tty->driver_data; |
| 244 | + struct tty0tty_serial *tty0tty_paired = NULL; | |
| 245 | + int index; | |
| 246 | + int paired_index; | |
| 232 | 247 | int room = -EINVAL; |
| 233 | 248 | |
| 234 | 249 | if (!tty0tty) |
| 235 | 250 | return -ENODEV; |
| 236 | 251 | |
| 237 | 252 | down(&tty0tty->sem); |
| 238 | - | |
| 253 | + | |
| 239 | 254 | if (!tty0tty->open_count) { |
| 240 | 255 | /* port was not opened */ |
| 241 | 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 | 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 | 276 | exit: |
| 248 | 277 | up(&tty0tty->sem); | ... | ... |