diff options
Diffstat (limited to 'drivers/tty/tty_buffer.c')
-rw-r--r-- | drivers/tty/tty_buffer.c | 265 |
1 files changed, 95 insertions, 170 deletions
diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c index 45d916198f7..6c9b7cd6778 100644 --- a/drivers/tty/tty_buffer.c +++ b/drivers/tty/tty_buffer.c | |||
@@ -27,21 +27,19 @@ | |||
27 | * Locking: none | 27 | * Locking: none |
28 | */ | 28 | */ |
29 | 29 | ||
30 | void tty_buffer_free_all(struct tty_port *port) | 30 | void tty_buffer_free_all(struct tty_struct *tty) |
31 | { | 31 | { |
32 | struct tty_bufhead *buf = &port->buf; | ||
33 | struct tty_buffer *thead; | 32 | struct tty_buffer *thead; |
34 | 33 | while ((thead = tty->buf.head) != NULL) { | |
35 | while ((thead = buf->head) != NULL) { | 34 | tty->buf.head = thead->next; |
36 | buf->head = thead->next; | ||
37 | kfree(thead); | 35 | kfree(thead); |
38 | } | 36 | } |
39 | while ((thead = buf->free) != NULL) { | 37 | while ((thead = tty->buf.free) != NULL) { |
40 | buf->free = thead->next; | 38 | tty->buf.free = thead->next; |
41 | kfree(thead); | 39 | kfree(thead); |
42 | } | 40 | } |
43 | buf->tail = NULL; | 41 | tty->buf.tail = NULL; |
44 | buf->memory_used = 0; | 42 | tty->buf.memory_used = 0; |
45 | } | 43 | } |
46 | 44 | ||
47 | /** | 45 | /** |
@@ -56,11 +54,11 @@ void tty_buffer_free_all(struct tty_port *port) | |||
56 | * Locking: Caller must hold tty->buf.lock | 54 | * Locking: Caller must hold tty->buf.lock |
57 | */ | 55 | */ |
58 | 56 | ||
59 | static struct tty_buffer *tty_buffer_alloc(struct tty_port *port, size_t size) | 57 | static struct tty_buffer *tty_buffer_alloc(struct tty_struct *tty, size_t size) |
60 | { | 58 | { |
61 | struct tty_buffer *p; | 59 | struct tty_buffer *p; |
62 | 60 | ||
63 | if (port->buf.memory_used + size > 65536) | 61 | if (tty->buf.memory_used + size > 65536) |
64 | return NULL; | 62 | return NULL; |
65 | p = kmalloc(sizeof(struct tty_buffer) + 2 * size, GFP_ATOMIC); | 63 | p = kmalloc(sizeof(struct tty_buffer) + 2 * size, GFP_ATOMIC); |
66 | if (p == NULL) | 64 | if (p == NULL) |
@@ -72,7 +70,7 @@ static struct tty_buffer *tty_buffer_alloc(struct tty_port *port, size_t size) | |||
72 | p->read = 0; | 70 | p->read = 0; |
73 | p->char_buf_ptr = (char *)(p->data); | 71 | p->char_buf_ptr = (char *)(p->data); |
74 | p->flag_buf_ptr = (unsigned char *)p->char_buf_ptr + size; | 72 | p->flag_buf_ptr = (unsigned char *)p->char_buf_ptr + size; |
75 | port->buf.memory_used += size; | 73 | tty->buf.memory_used += size; |
76 | return p; | 74 | return p; |
77 | } | 75 | } |
78 | 76 | ||
@@ -87,19 +85,17 @@ static struct tty_buffer *tty_buffer_alloc(struct tty_port *port, size_t size) | |||
87 | * Locking: Caller must hold tty->buf.lock | 85 | * Locking: Caller must hold tty->buf.lock |
88 | */ | 86 | */ |
89 | 87 | ||
90 | static void tty_buffer_free(struct tty_port *port, struct tty_buffer *b) | 88 | static void tty_buffer_free(struct tty_struct *tty, struct tty_buffer *b) |
91 | { | 89 | { |
92 | struct tty_bufhead *buf = &port->buf; | ||
93 | |||
94 | /* Dumb strategy for now - should keep some stats */ | 90 | /* Dumb strategy for now - should keep some stats */ |
95 | buf->memory_used -= b->size; | 91 | tty->buf.memory_used -= b->size; |
96 | WARN_ON(buf->memory_used < 0); | 92 | WARN_ON(tty->buf.memory_used < 0); |
97 | 93 | ||
98 | if (b->size >= 512) | 94 | if (b->size >= 512) |
99 | kfree(b); | 95 | kfree(b); |
100 | else { | 96 | else { |
101 | b->next = buf->free; | 97 | b->next = tty->buf.free; |
102 | buf->free = b; | 98 | tty->buf.free = b; |
103 | } | 99 | } |
104 | } | 100 | } |
105 | 101 | ||
@@ -114,16 +110,15 @@ static void tty_buffer_free(struct tty_port *port, struct tty_buffer *b) | |||
114 | * Locking: Caller must hold tty->buf.lock | 110 | * Locking: Caller must hold tty->buf.lock |
115 | */ | 111 | */ |
116 | 112 | ||
117 | static void __tty_buffer_flush(struct tty_port *port) | 113 | static void __tty_buffer_flush(struct tty_struct *tty) |
118 | { | 114 | { |
119 | struct tty_bufhead *buf = &port->buf; | ||
120 | struct tty_buffer *thead; | 115 | struct tty_buffer *thead; |
121 | 116 | ||
122 | while ((thead = buf->head) != NULL) { | 117 | while ((thead = tty->buf.head) != NULL) { |
123 | buf->head = thead->next; | 118 | tty->buf.head = thead->next; |
124 | tty_buffer_free(port, thead); | 119 | tty_buffer_free(tty, thead); |
125 | } | 120 | } |
126 | buf->tail = NULL; | 121 | tty->buf.tail = NULL; |
127 | } | 122 | } |
128 | 123 | ||
129 | /** | 124 | /** |
@@ -139,24 +134,21 @@ static void __tty_buffer_flush(struct tty_port *port) | |||
139 | 134 | ||
140 | void tty_buffer_flush(struct tty_struct *tty) | 135 | void tty_buffer_flush(struct tty_struct *tty) |
141 | { | 136 | { |
142 | struct tty_port *port = tty->port; | ||
143 | struct tty_bufhead *buf = &port->buf; | ||
144 | unsigned long flags; | 137 | unsigned long flags; |
145 | 138 | spin_lock_irqsave(&tty->buf.lock, flags); | |
146 | spin_lock_irqsave(&buf->lock, flags); | ||
147 | 139 | ||
148 | /* If the data is being pushed to the tty layer then we can't | 140 | /* If the data is being pushed to the tty layer then we can't |
149 | process it here. Instead set a flag and the flush_to_ldisc | 141 | process it here. Instead set a flag and the flush_to_ldisc |
150 | path will process the flush request before it exits */ | 142 | path will process the flush request before it exits */ |
151 | if (test_bit(TTYP_FLUSHING, &port->iflags)) { | 143 | if (test_bit(TTY_FLUSHING, &tty->flags)) { |
152 | set_bit(TTYP_FLUSHPENDING, &port->iflags); | 144 | set_bit(TTY_FLUSHPENDING, &tty->flags); |
153 | spin_unlock_irqrestore(&buf->lock, flags); | 145 | spin_unlock_irqrestore(&tty->buf.lock, flags); |
154 | wait_event(tty->read_wait, | 146 | wait_event(tty->read_wait, |
155 | test_bit(TTYP_FLUSHPENDING, &port->iflags) == 0); | 147 | test_bit(TTY_FLUSHPENDING, &tty->flags) == 0); |
156 | return; | 148 | return; |
157 | } else | 149 | } else |
158 | __tty_buffer_flush(port); | 150 | __tty_buffer_flush(tty); |
159 | spin_unlock_irqrestore(&buf->lock, flags); | 151 | spin_unlock_irqrestore(&tty->buf.lock, flags); |
160 | } | 152 | } |
161 | 153 | ||
162 | /** | 154 | /** |
@@ -171,9 +163,9 @@ void tty_buffer_flush(struct tty_struct *tty) | |||
171 | * Locking: Caller must hold tty->buf.lock | 163 | * Locking: Caller must hold tty->buf.lock |
172 | */ | 164 | */ |
173 | 165 | ||
174 | static struct tty_buffer *tty_buffer_find(struct tty_port *port, size_t size) | 166 | static struct tty_buffer *tty_buffer_find(struct tty_struct *tty, size_t size) |
175 | { | 167 | { |
176 | struct tty_buffer **tbh = &port->buf.free; | 168 | struct tty_buffer **tbh = &tty->buf.free; |
177 | while ((*tbh) != NULL) { | 169 | while ((*tbh) != NULL) { |
178 | struct tty_buffer *t = *tbh; | 170 | struct tty_buffer *t = *tbh; |
179 | if (t->size >= size) { | 171 | if (t->size >= size) { |
@@ -182,78 +174,60 @@ static struct tty_buffer *tty_buffer_find(struct tty_port *port, size_t size) | |||
182 | t->used = 0; | 174 | t->used = 0; |
183 | t->commit = 0; | 175 | t->commit = 0; |
184 | t->read = 0; | 176 | t->read = 0; |
185 | port->buf.memory_used += t->size; | 177 | tty->buf.memory_used += t->size; |
186 | return t; | 178 | return t; |
187 | } | 179 | } |
188 | tbh = &((*tbh)->next); | 180 | tbh = &((*tbh)->next); |
189 | } | 181 | } |
190 | /* Round the buffer size out */ | 182 | /* Round the buffer size out */ |
191 | size = (size + 0xFF) & ~0xFF; | 183 | size = (size + 0xFF) & ~0xFF; |
192 | return tty_buffer_alloc(port, size); | 184 | return tty_buffer_alloc(tty, size); |
193 | /* Should possibly check if this fails for the largest buffer we | 185 | /* Should possibly check if this fails for the largest buffer we |
194 | have queued and recycle that ? */ | 186 | have queued and recycle that ? */ |
195 | } | 187 | } |
188 | |||
196 | /** | 189 | /** |
197 | * __tty_buffer_request_room - grow tty buffer if needed | 190 | * tty_buffer_request_room - grow tty buffer if needed |
198 | * @tty: tty structure | 191 | * @tty: tty structure |
199 | * @size: size desired | 192 | * @size: size desired |
200 | * | 193 | * |
201 | * Make at least size bytes of linear space available for the tty | 194 | * Make at least size bytes of linear space available for the tty |
202 | * buffer. If we fail return the size we managed to find. | 195 | * buffer. If we fail return the size we managed to find. |
203 | * Locking: Caller must hold port->buf.lock | 196 | * |
197 | * Locking: Takes tty->buf.lock | ||
204 | */ | 198 | */ |
205 | static int __tty_buffer_request_room(struct tty_port *port, size_t size) | 199 | int tty_buffer_request_room(struct tty_struct *tty, size_t size) |
206 | { | 200 | { |
207 | struct tty_bufhead *buf = &port->buf; | ||
208 | struct tty_buffer *b, *n; | 201 | struct tty_buffer *b, *n; |
209 | int left; | 202 | int left; |
203 | unsigned long flags; | ||
204 | |||
205 | spin_lock_irqsave(&tty->buf.lock, flags); | ||
206 | |||
210 | /* OPTIMISATION: We could keep a per tty "zero" sized buffer to | 207 | /* OPTIMISATION: We could keep a per tty "zero" sized buffer to |
211 | remove this conditional if its worth it. This would be invisible | 208 | remove this conditional if its worth it. This would be invisible |
212 | to the callers */ | 209 | to the callers */ |
213 | b = buf->tail; | 210 | if ((b = tty->buf.tail) != NULL) |
214 | if (b != NULL) | ||
215 | left = b->size - b->used; | 211 | left = b->size - b->used; |
216 | else | 212 | else |
217 | left = 0; | 213 | left = 0; |
218 | 214 | ||
219 | if (left < size) { | 215 | if (left < size) { |
220 | /* This is the slow path - looking for new buffers to use */ | 216 | /* This is the slow path - looking for new buffers to use */ |
221 | if ((n = tty_buffer_find(port, size)) != NULL) { | 217 | if ((n = tty_buffer_find(tty, size)) != NULL) { |
222 | if (b != NULL) { | 218 | if (b != NULL) { |
223 | b->next = n; | 219 | b->next = n; |
224 | b->commit = b->used; | 220 | b->commit = b->used; |
225 | } else | 221 | } else |
226 | buf->head = n; | 222 | tty->buf.head = n; |
227 | buf->tail = n; | 223 | tty->buf.tail = n; |
228 | } else | 224 | } else |
229 | size = left; | 225 | size = left; |
230 | } | 226 | } |
231 | 227 | ||
228 | spin_unlock_irqrestore(&tty->buf.lock, flags); | ||
232 | return size; | 229 | return size; |
233 | } | 230 | } |
234 | |||
235 | |||
236 | /** | ||
237 | * tty_buffer_request_room - grow tty buffer if needed | ||
238 | * @tty: tty structure | ||
239 | * @size: size desired | ||
240 | * | ||
241 | * Make at least size bytes of linear space available for the tty | ||
242 | * buffer. If we fail return the size we managed to find. | ||
243 | * | ||
244 | * Locking: Takes port->buf.lock | ||
245 | */ | ||
246 | int tty_buffer_request_room(struct tty_struct *tty, size_t size) | ||
247 | { | ||
248 | struct tty_port *port = tty->port; | ||
249 | unsigned long flags; | ||
250 | int length; | ||
251 | |||
252 | spin_lock_irqsave(&port->buf.lock, flags); | ||
253 | length = __tty_buffer_request_room(port, size); | ||
254 | spin_unlock_irqrestore(&port->buf.lock, flags); | ||
255 | return length; | ||
256 | } | ||
257 | EXPORT_SYMBOL_GPL(tty_buffer_request_room); | 231 | EXPORT_SYMBOL_GPL(tty_buffer_request_room); |
258 | 232 | ||
259 | /** | 233 | /** |
@@ -266,32 +240,23 @@ EXPORT_SYMBOL_GPL(tty_buffer_request_room); | |||
266 | * Queue a series of bytes to the tty buffering. All the characters | 240 | * Queue a series of bytes to the tty buffering. All the characters |
267 | * passed are marked with the supplied flag. Returns the number added. | 241 | * passed are marked with the supplied flag. Returns the number added. |
268 | * | 242 | * |
269 | * Locking: Called functions may take port->buf.lock | 243 | * Locking: Called functions may take tty->buf.lock |
270 | */ | 244 | */ |
271 | 245 | ||
272 | int tty_insert_flip_string_fixed_flag(struct tty_struct *tty, | 246 | int tty_insert_flip_string_fixed_flag(struct tty_struct *tty, |
273 | const unsigned char *chars, char flag, size_t size) | 247 | const unsigned char *chars, char flag, size_t size) |
274 | { | 248 | { |
275 | struct tty_bufhead *buf = &tty->port->buf; | ||
276 | int copied = 0; | 249 | int copied = 0; |
277 | do { | 250 | do { |
278 | int goal = min_t(size_t, size - copied, TTY_BUFFER_PAGE); | 251 | int goal = min_t(size_t, size - copied, TTY_BUFFER_PAGE); |
279 | int space; | 252 | int space = tty_buffer_request_room(tty, goal); |
280 | unsigned long flags; | 253 | struct tty_buffer *tb = tty->buf.tail; |
281 | struct tty_buffer *tb; | ||
282 | |||
283 | spin_lock_irqsave(&buf->lock, flags); | ||
284 | space = __tty_buffer_request_room(tty->port, goal); | ||
285 | tb = buf->tail; | ||
286 | /* If there is no space then tb may be NULL */ | 254 | /* If there is no space then tb may be NULL */ |
287 | if (unlikely(space == 0)) { | 255 | if (unlikely(space == 0)) |
288 | spin_unlock_irqrestore(&buf->lock, flags); | ||
289 | break; | 256 | break; |
290 | } | ||
291 | memcpy(tb->char_buf_ptr + tb->used, chars, space); | 257 | memcpy(tb->char_buf_ptr + tb->used, chars, space); |
292 | memset(tb->flag_buf_ptr + tb->used, flag, space); | 258 | memset(tb->flag_buf_ptr + tb->used, flag, space); |
293 | tb->used += space; | 259 | tb->used += space; |
294 | spin_unlock_irqrestore(&buf->lock, flags); | ||
295 | copied += space; | 260 | copied += space; |
296 | chars += space; | 261 | chars += space; |
297 | /* There is a small chance that we need to split the data over | 262 | /* There is a small chance that we need to split the data over |
@@ -312,32 +277,23 @@ EXPORT_SYMBOL(tty_insert_flip_string_fixed_flag); | |||
312 | * the flags array indicates the status of the character. Returns the | 277 | * the flags array indicates the status of the character. Returns the |
313 | * number added. | 278 | * number added. |
314 | * | 279 | * |
315 | * Locking: Called functions may take port->buf.lock | 280 | * Locking: Called functions may take tty->buf.lock |
316 | */ | 281 | */ |
317 | 282 | ||
318 | int tty_insert_flip_string_flags(struct tty_struct *tty, | 283 | int tty_insert_flip_string_flags(struct tty_struct *tty, |
319 | const unsigned char *chars, const char *flags, size_t size) | 284 | const unsigned char *chars, const char *flags, size_t size) |
320 | { | 285 | { |
321 | struct tty_bufhead *buf = &tty->port->buf; | ||
322 | int copied = 0; | 286 | int copied = 0; |
323 | do { | 287 | do { |
324 | int goal = min_t(size_t, size - copied, TTY_BUFFER_PAGE); | 288 | int goal = min_t(size_t, size - copied, TTY_BUFFER_PAGE); |
325 | int space; | 289 | int space = tty_buffer_request_room(tty, goal); |
326 | unsigned long __flags; | 290 | struct tty_buffer *tb = tty->buf.tail; |
327 | struct tty_buffer *tb; | ||
328 | |||
329 | spin_lock_irqsave(&buf->lock, __flags); | ||
330 | space = __tty_buffer_request_room(tty->port, goal); | ||
331 | tb = buf->tail; | ||
332 | /* If there is no space then tb may be NULL */ | 291 | /* If there is no space then tb may be NULL */ |
333 | if (unlikely(space == 0)) { | 292 | if (unlikely(space == 0)) |
334 | spin_unlock_irqrestore(&buf->lock, __flags); | ||
335 | break; | 293 | break; |
336 | } | ||
337 | memcpy(tb->char_buf_ptr + tb->used, chars, space); | 294 | memcpy(tb->char_buf_ptr + tb->used, chars, space); |
338 | memcpy(tb->flag_buf_ptr + tb->used, flags, space); | 295 | memcpy(tb->flag_buf_ptr + tb->used, flags, space); |
339 | tb->used += space; | 296 | tb->used += space; |
340 | spin_unlock_irqrestore(&buf->lock, __flags); | ||
341 | copied += space; | 297 | copied += space; |
342 | chars += space; | 298 | chars += space; |
343 | flags += space; | 299 | flags += space; |
@@ -355,23 +311,18 @@ EXPORT_SYMBOL(tty_insert_flip_string_flags); | |||
355 | * Takes any pending buffers and transfers their ownership to the | 311 | * Takes any pending buffers and transfers their ownership to the |
356 | * ldisc side of the queue. It then schedules those characters for | 312 | * ldisc side of the queue. It then schedules those characters for |
357 | * processing by the line discipline. | 313 | * processing by the line discipline. |
358 | * Note that this function can only be used when the low_latency flag | ||
359 | * is unset. Otherwise the workqueue won't be flushed. | ||
360 | * | 314 | * |
361 | * Locking: Takes port->buf.lock | 315 | * Locking: Takes tty->buf.lock |
362 | */ | 316 | */ |
363 | 317 | ||
364 | void tty_schedule_flip(struct tty_struct *tty) | 318 | void tty_schedule_flip(struct tty_struct *tty) |
365 | { | 319 | { |
366 | struct tty_bufhead *buf = &tty->port->buf; | ||
367 | unsigned long flags; | 320 | unsigned long flags; |
368 | WARN_ON(tty->low_latency); | 321 | spin_lock_irqsave(&tty->buf.lock, flags); |
369 | 322 | if (tty->buf.tail != NULL) | |
370 | spin_lock_irqsave(&buf->lock, flags); | 323 | tty->buf.tail->commit = tty->buf.tail->used; |
371 | if (buf->tail != NULL) | 324 | spin_unlock_irqrestore(&tty->buf.lock, flags); |
372 | buf->tail->commit = buf->tail->used; | 325 | schedule_work(&tty->buf.work); |
373 | spin_unlock_irqrestore(&buf->lock, flags); | ||
374 | schedule_work(&buf->work); | ||
375 | } | 326 | } |
376 | EXPORT_SYMBOL(tty_schedule_flip); | 327 | EXPORT_SYMBOL(tty_schedule_flip); |
377 | 328 | ||
@@ -387,27 +338,19 @@ EXPORT_SYMBOL(tty_schedule_flip); | |||
387 | * that need their own block copy routines into the buffer. There is no | 338 | * that need their own block copy routines into the buffer. There is no |
388 | * guarantee the buffer is a DMA target! | 339 | * guarantee the buffer is a DMA target! |
389 | * | 340 | * |
390 | * Locking: May call functions taking port->buf.lock | 341 | * Locking: May call functions taking tty->buf.lock |
391 | */ | 342 | */ |
392 | 343 | ||
393 | int tty_prepare_flip_string(struct tty_struct *tty, unsigned char **chars, | 344 | int tty_prepare_flip_string(struct tty_struct *tty, unsigned char **chars, |
394 | size_t size) | 345 | size_t size) |
395 | { | 346 | { |
396 | struct tty_bufhead *buf = &tty->port->buf; | 347 | int space = tty_buffer_request_room(tty, size); |
397 | int space; | ||
398 | unsigned long flags; | ||
399 | struct tty_buffer *tb; | ||
400 | |||
401 | spin_lock_irqsave(&buf->lock, flags); | ||
402 | space = __tty_buffer_request_room(tty->port, size); | ||
403 | |||
404 | tb = buf->tail; | ||
405 | if (likely(space)) { | 348 | if (likely(space)) { |
349 | struct tty_buffer *tb = tty->buf.tail; | ||
406 | *chars = tb->char_buf_ptr + tb->used; | 350 | *chars = tb->char_buf_ptr + tb->used; |
407 | memset(tb->flag_buf_ptr + tb->used, TTY_NORMAL, space); | 351 | memset(tb->flag_buf_ptr + tb->used, TTY_NORMAL, space); |
408 | tb->used += space; | 352 | tb->used += space; |
409 | } | 353 | } |
410 | spin_unlock_irqrestore(&buf->lock, flags); | ||
411 | return space; | 354 | return space; |
412 | } | 355 | } |
413 | EXPORT_SYMBOL_GPL(tty_prepare_flip_string); | 356 | EXPORT_SYMBOL_GPL(tty_prepare_flip_string); |
@@ -425,27 +368,19 @@ EXPORT_SYMBOL_GPL(tty_prepare_flip_string); | |||
425 | * that need their own block copy routines into the buffer. There is no | 368 | * that need their own block copy routines into the buffer. There is no |
426 | * guarantee the buffer is a DMA target! | 369 | * guarantee the buffer is a DMA target! |
427 | * | 370 | * |
428 | * Locking: May call functions taking port->buf.lock | 371 | * Locking: May call functions taking tty->buf.lock |
429 | */ | 372 | */ |
430 | 373 | ||
431 | int tty_prepare_flip_string_flags(struct tty_struct *tty, | 374 | int tty_prepare_flip_string_flags(struct tty_struct *tty, |
432 | unsigned char **chars, char **flags, size_t size) | 375 | unsigned char **chars, char **flags, size_t size) |
433 | { | 376 | { |
434 | struct tty_bufhead *buf = &tty->port->buf; | 377 | int space = tty_buffer_request_room(tty, size); |
435 | int space; | ||
436 | unsigned long __flags; | ||
437 | struct tty_buffer *tb; | ||
438 | |||
439 | spin_lock_irqsave(&buf->lock, __flags); | ||
440 | space = __tty_buffer_request_room(tty->port, size); | ||
441 | |||
442 | tb = buf->tail; | ||
443 | if (likely(space)) { | 378 | if (likely(space)) { |
379 | struct tty_buffer *tb = tty->buf.tail; | ||
444 | *chars = tb->char_buf_ptr + tb->used; | 380 | *chars = tb->char_buf_ptr + tb->used; |
445 | *flags = tb->flag_buf_ptr + tb->used; | 381 | *flags = tb->flag_buf_ptr + tb->used; |
446 | tb->used += space; | 382 | tb->used += space; |
447 | } | 383 | } |
448 | spin_unlock_irqrestore(&buf->lock, __flags); | ||
449 | return space; | 384 | return space; |
450 | } | 385 | } |
451 | EXPORT_SYMBOL_GPL(tty_prepare_flip_string_flags); | 386 | EXPORT_SYMBOL_GPL(tty_prepare_flip_string_flags); |
@@ -466,25 +401,20 @@ EXPORT_SYMBOL_GPL(tty_prepare_flip_string_flags); | |||
466 | 401 | ||
467 | static void flush_to_ldisc(struct work_struct *work) | 402 | static void flush_to_ldisc(struct work_struct *work) |
468 | { | 403 | { |
469 | struct tty_port *port = container_of(work, struct tty_port, buf.work); | 404 | struct tty_struct *tty = |
470 | struct tty_bufhead *buf = &port->buf; | 405 | container_of(work, struct tty_struct, buf.work); |
471 | struct tty_struct *tty; | ||
472 | unsigned long flags; | 406 | unsigned long flags; |
473 | struct tty_ldisc *disc; | 407 | struct tty_ldisc *disc; |
474 | 408 | ||
475 | tty = port->itty; | ||
476 | if (WARN_RATELIMIT(tty == NULL, "tty is NULL\n")) | ||
477 | return; | ||
478 | |||
479 | disc = tty_ldisc_ref(tty); | 409 | disc = tty_ldisc_ref(tty); |
480 | if (disc == NULL) /* !TTY_LDISC */ | 410 | if (disc == NULL) /* !TTY_LDISC */ |
481 | return; | 411 | return; |
482 | 412 | ||
483 | spin_lock_irqsave(&buf->lock, flags); | 413 | spin_lock_irqsave(&tty->buf.lock, flags); |
484 | 414 | ||
485 | if (!test_and_set_bit(TTYP_FLUSHING, &port->iflags)) { | 415 | if (!test_and_set_bit(TTY_FLUSHING, &tty->flags)) { |
486 | struct tty_buffer *head; | 416 | struct tty_buffer *head; |
487 | while ((head = buf->head) != NULL) { | 417 | while ((head = tty->buf.head) != NULL) { |
488 | int count; | 418 | int count; |
489 | char *char_buf; | 419 | char *char_buf; |
490 | unsigned char *flag_buf; | 420 | unsigned char *flag_buf; |
@@ -493,14 +423,14 @@ static void flush_to_ldisc(struct work_struct *work) | |||
493 | if (!count) { | 423 | if (!count) { |
494 | if (head->next == NULL) | 424 | if (head->next == NULL) |
495 | break; | 425 | break; |
496 | buf->head = head->next; | 426 | tty->buf.head = head->next; |
497 | tty_buffer_free(port, head); | 427 | tty_buffer_free(tty, head); |
498 | continue; | 428 | continue; |
499 | } | 429 | } |
500 | /* Ldisc or user is trying to flush the buffers | 430 | /* Ldisc or user is trying to flush the buffers |
501 | we are feeding to the ldisc, stop feeding the | 431 | we are feeding to the ldisc, stop feeding the |
502 | line discipline as we want to empty the queue */ | 432 | line discipline as we want to empty the queue */ |
503 | if (test_bit(TTYP_FLUSHPENDING, &port->iflags)) | 433 | if (test_bit(TTY_FLUSHPENDING, &tty->flags)) |
504 | break; | 434 | break; |
505 | if (!tty->receive_room) | 435 | if (!tty->receive_room) |
506 | break; | 436 | break; |
@@ -509,22 +439,22 @@ static void flush_to_ldisc(struct work_struct *work) | |||
509 | char_buf = head->char_buf_ptr + head->read; | 439 | char_buf = head->char_buf_ptr + head->read; |
510 | flag_buf = head->flag_buf_ptr + head->read; | 440 | flag_buf = head->flag_buf_ptr + head->read; |
511 | head->read += count; | 441 | head->read += count; |
512 | spin_unlock_irqrestore(&buf->lock, flags); | 442 | spin_unlock_irqrestore(&tty->buf.lock, flags); |
513 | disc->ops->receive_buf(tty, char_buf, | 443 | disc->ops->receive_buf(tty, char_buf, |
514 | flag_buf, count); | 444 | flag_buf, count); |
515 | spin_lock_irqsave(&buf->lock, flags); | 445 | spin_lock_irqsave(&tty->buf.lock, flags); |
516 | } | 446 | } |
517 | clear_bit(TTYP_FLUSHING, &port->iflags); | 447 | clear_bit(TTY_FLUSHING, &tty->flags); |
518 | } | 448 | } |
519 | 449 | ||
520 | /* We may have a deferred request to flush the input buffer, | 450 | /* We may have a deferred request to flush the input buffer, |
521 | if so pull the chain under the lock and empty the queue */ | 451 | if so pull the chain under the lock and empty the queue */ |
522 | if (test_bit(TTYP_FLUSHPENDING, &port->iflags)) { | 452 | if (test_bit(TTY_FLUSHPENDING, &tty->flags)) { |
523 | __tty_buffer_flush(port); | 453 | __tty_buffer_flush(tty); |
524 | clear_bit(TTYP_FLUSHPENDING, &port->iflags); | 454 | clear_bit(TTY_FLUSHPENDING, &tty->flags); |
525 | wake_up(&tty->read_wait); | 455 | wake_up(&tty->read_wait); |
526 | } | 456 | } |
527 | spin_unlock_irqrestore(&buf->lock, flags); | 457 | spin_unlock_irqrestore(&tty->buf.lock, flags); |
528 | 458 | ||
529 | tty_ldisc_deref(disc); | 459 | tty_ldisc_deref(disc); |
530 | } | 460 | } |
@@ -539,8 +469,7 @@ static void flush_to_ldisc(struct work_struct *work) | |||
539 | */ | 469 | */ |
540 | void tty_flush_to_ldisc(struct tty_struct *tty) | 470 | void tty_flush_to_ldisc(struct tty_struct *tty) |
541 | { | 471 | { |
542 | if (!tty->low_latency) | 472 | flush_work(&tty->buf.work); |
543 | flush_work(&tty->port->buf.work); | ||
544 | } | 473 | } |
545 | 474 | ||
546 | /** | 475 | /** |
@@ -558,18 +487,16 @@ void tty_flush_to_ldisc(struct tty_struct *tty) | |||
558 | 487 | ||
559 | void tty_flip_buffer_push(struct tty_struct *tty) | 488 | void tty_flip_buffer_push(struct tty_struct *tty) |
560 | { | 489 | { |
561 | struct tty_bufhead *buf = &tty->port->buf; | ||
562 | unsigned long flags; | 490 | unsigned long flags; |
563 | 491 | spin_lock_irqsave(&tty->buf.lock, flags); | |
564 | spin_lock_irqsave(&buf->lock, flags); | 492 | if (tty->buf.tail != NULL) |
565 | if (buf->tail != NULL) | 493 | tty->buf.tail->commit = tty->buf.tail->used; |
566 | buf->tail->commit = buf->tail->used; | 494 | spin_unlock_irqrestore(&tty->buf.lock, flags); |
567 | spin_unlock_irqrestore(&buf->lock, flags); | ||
568 | 495 | ||
569 | if (tty->low_latency) | 496 | if (tty->low_latency) |
570 | flush_to_ldisc(&buf->work); | 497 | flush_to_ldisc(&tty->buf.work); |
571 | else | 498 | else |
572 | schedule_work(&buf->work); | 499 | schedule_work(&tty->buf.work); |
573 | } | 500 | } |
574 | EXPORT_SYMBOL(tty_flip_buffer_push); | 501 | EXPORT_SYMBOL(tty_flip_buffer_push); |
575 | 502 | ||
@@ -583,15 +510,13 @@ EXPORT_SYMBOL(tty_flip_buffer_push); | |||
583 | * Locking: none | 510 | * Locking: none |
584 | */ | 511 | */ |
585 | 512 | ||
586 | void tty_buffer_init(struct tty_port *port) | 513 | void tty_buffer_init(struct tty_struct *tty) |
587 | { | 514 | { |
588 | struct tty_bufhead *buf = &port->buf; | 515 | spin_lock_init(&tty->buf.lock); |
589 | 516 | tty->buf.head = NULL; | |
590 | spin_lock_init(&buf->lock); | 517 | tty->buf.tail = NULL; |
591 | buf->head = NULL; | 518 | tty->buf.free = NULL; |
592 | buf->tail = NULL; | 519 | tty->buf.memory_used = 0; |
593 | buf->free = NULL; | 520 | INIT_WORK(&tty->buf.work, flush_to_ldisc); |
594 | buf->memory_used = 0; | ||
595 | INIT_WORK(&buf->work, flush_to_ldisc); | ||
596 | } | 521 | } |
597 | 522 | ||