diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/bluetooth/rfcomm/tty.c | 10 | ||||
-rw-r--r-- | net/irda/ircomm/ircomm_param.c | 5 | ||||
-rw-r--r-- | net/irda/ircomm/ircomm_tty.c | 320 | ||||
-rw-r--r-- | net/irda/ircomm/ircomm_tty_attach.c | 40 | ||||
-rw-r--r-- | net/irda/ircomm/ircomm_tty_ioctl.c | 33 |
5 files changed, 205 insertions, 203 deletions
diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c index 56f182393c4c..ccc248791d50 100644 --- a/net/bluetooth/rfcomm/tty.c +++ b/net/bluetooth/rfcomm/tty.c | |||
@@ -278,8 +278,8 @@ out: | |||
278 | if (err < 0) | 278 | if (err < 0) |
279 | goto free; | 279 | goto free; |
280 | 280 | ||
281 | dev->tty_dev = tty_register_device(rfcomm_tty_driver, dev->id, NULL); | 281 | dev->tty_dev = tty_port_register_device(&dev->port, rfcomm_tty_driver, |
282 | 282 | dev->id, NULL); | |
283 | if (IS_ERR(dev->tty_dev)) { | 283 | if (IS_ERR(dev->tty_dev)) { |
284 | err = PTR_ERR(dev->tty_dev); | 284 | err = PTR_ERR(dev->tty_dev); |
285 | list_del(&dev->list); | 285 | list_del(&dev->list); |
@@ -705,9 +705,9 @@ static int rfcomm_tty_open(struct tty_struct *tty, struct file *filp) | |||
705 | break; | 705 | break; |
706 | } | 706 | } |
707 | 707 | ||
708 | tty_unlock(); | 708 | tty_unlock(tty); |
709 | schedule(); | 709 | schedule(); |
710 | tty_lock(); | 710 | tty_lock(tty); |
711 | } | 711 | } |
712 | set_current_state(TASK_RUNNING); | 712 | set_current_state(TASK_RUNNING); |
713 | remove_wait_queue(&dev->wait, &wait); | 713 | remove_wait_queue(&dev->wait, &wait); |
@@ -861,7 +861,7 @@ static int rfcomm_tty_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned l | |||
861 | 861 | ||
862 | static void rfcomm_tty_set_termios(struct tty_struct *tty, struct ktermios *old) | 862 | static void rfcomm_tty_set_termios(struct tty_struct *tty, struct ktermios *old) |
863 | { | 863 | { |
864 | struct ktermios *new = tty->termios; | 864 | struct ktermios *new = &tty->termios; |
865 | int old_baud_rate = tty_termios_baud_rate(old); | 865 | int old_baud_rate = tty_termios_baud_rate(old); |
866 | int new_baud_rate = tty_termios_baud_rate(new); | 866 | int new_baud_rate = tty_termios_baud_rate(new); |
867 | 867 | ||
diff --git a/net/irda/ircomm/ircomm_param.c b/net/irda/ircomm/ircomm_param.c index 8b915f3ac3b9..308939128359 100644 --- a/net/irda/ircomm/ircomm_param.c +++ b/net/irda/ircomm/ircomm_param.c | |||
@@ -99,7 +99,6 @@ pi_param_info_t ircomm_param_info = { pi_major_call_table, 3, 0x0f, 4 }; | |||
99 | */ | 99 | */ |
100 | int ircomm_param_request(struct ircomm_tty_cb *self, __u8 pi, int flush) | 100 | int ircomm_param_request(struct ircomm_tty_cb *self, __u8 pi, int flush) |
101 | { | 101 | { |
102 | struct tty_struct *tty; | ||
103 | unsigned long flags; | 102 | unsigned long flags; |
104 | struct sk_buff *skb; | 103 | struct sk_buff *skb; |
105 | int count; | 104 | int count; |
@@ -109,10 +108,6 @@ int ircomm_param_request(struct ircomm_tty_cb *self, __u8 pi, int flush) | |||
109 | IRDA_ASSERT(self != NULL, return -1;); | 108 | IRDA_ASSERT(self != NULL, return -1;); |
110 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;); | 109 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;); |
111 | 110 | ||
112 | tty = self->tty; | ||
113 | if (!tty) | ||
114 | return 0; | ||
115 | |||
116 | /* Make sure we don't send parameters for raw mode */ | 111 | /* Make sure we don't send parameters for raw mode */ |
117 | if (self->service_type == IRCOMM_3_WIRE_RAW) | 112 | if (self->service_type == IRCOMM_3_WIRE_RAW) |
118 | return 0; | 113 | return 0; |
diff --git a/net/irda/ircomm/ircomm_tty.c b/net/irda/ircomm/ircomm_tty.c index 6b9d5a0e42f9..95a3a7a336ba 100644 --- a/net/irda/ircomm/ircomm_tty.c +++ b/net/irda/ircomm/ircomm_tty.c | |||
@@ -52,6 +52,8 @@ | |||
52 | #include <net/irda/ircomm_tty_attach.h> | 52 | #include <net/irda/ircomm_tty_attach.h> |
53 | #include <net/irda/ircomm_tty.h> | 53 | #include <net/irda/ircomm_tty.h> |
54 | 54 | ||
55 | static int ircomm_tty_install(struct tty_driver *driver, | ||
56 | struct tty_struct *tty); | ||
55 | static int ircomm_tty_open(struct tty_struct *tty, struct file *filp); | 57 | static int ircomm_tty_open(struct tty_struct *tty, struct file *filp); |
56 | static void ircomm_tty_close(struct tty_struct * tty, struct file *filp); | 58 | static void ircomm_tty_close(struct tty_struct * tty, struct file *filp); |
57 | static int ircomm_tty_write(struct tty_struct * tty, | 59 | static int ircomm_tty_write(struct tty_struct * tty, |
@@ -82,6 +84,7 @@ static struct tty_driver *driver; | |||
82 | static hashbin_t *ircomm_tty = NULL; | 84 | static hashbin_t *ircomm_tty = NULL; |
83 | 85 | ||
84 | static const struct tty_operations ops = { | 86 | static const struct tty_operations ops = { |
87 | .install = ircomm_tty_install, | ||
85 | .open = ircomm_tty_open, | 88 | .open = ircomm_tty_open, |
86 | .close = ircomm_tty_close, | 89 | .close = ircomm_tty_close, |
87 | .write = ircomm_tty_write, | 90 | .write = ircomm_tty_write, |
@@ -104,6 +107,35 @@ static const struct tty_operations ops = { | |||
104 | #endif /* CONFIG_PROC_FS */ | 107 | #endif /* CONFIG_PROC_FS */ |
105 | }; | 108 | }; |
106 | 109 | ||
110 | static void ircomm_port_raise_dtr_rts(struct tty_port *port, int raise) | ||
111 | { | ||
112 | struct ircomm_tty_cb *self = container_of(port, struct ircomm_tty_cb, | ||
113 | port); | ||
114 | /* | ||
115 | * Here, we use to lock those two guys, but as ircomm_param_request() | ||
116 | * does it itself, I don't see the point (and I see the deadlock). | ||
117 | * Jean II | ||
118 | */ | ||
119 | if (raise) | ||
120 | self->settings.dte |= IRCOMM_RTS | IRCOMM_DTR; | ||
121 | else | ||
122 | self->settings.dte &= ~(IRCOMM_RTS | IRCOMM_DTR); | ||
123 | |||
124 | ircomm_param_request(self, IRCOMM_DTE, TRUE); | ||
125 | } | ||
126 | |||
127 | static int ircomm_port_carrier_raised(struct tty_port *port) | ||
128 | { | ||
129 | struct ircomm_tty_cb *self = container_of(port, struct ircomm_tty_cb, | ||
130 | port); | ||
131 | return self->settings.dce & IRCOMM_CD; | ||
132 | } | ||
133 | |||
134 | static const struct tty_port_operations ircomm_port_ops = { | ||
135 | .dtr_rts = ircomm_port_raise_dtr_rts, | ||
136 | .carrier_raised = ircomm_port_carrier_raised, | ||
137 | }; | ||
138 | |||
107 | /* | 139 | /* |
108 | * Function ircomm_tty_init() | 140 | * Function ircomm_tty_init() |
109 | * | 141 | * |
@@ -194,7 +226,7 @@ static int ircomm_tty_startup(struct ircomm_tty_cb *self) | |||
194 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;); | 226 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;); |
195 | 227 | ||
196 | /* Check if already open */ | 228 | /* Check if already open */ |
197 | if (test_and_set_bit(ASYNC_B_INITIALIZED, &self->flags)) { | 229 | if (test_and_set_bit(ASYNCB_INITIALIZED, &self->port.flags)) { |
198 | IRDA_DEBUG(2, "%s(), already open so break out!\n", __func__ ); | 230 | IRDA_DEBUG(2, "%s(), already open so break out!\n", __func__ ); |
199 | return 0; | 231 | return 0; |
200 | } | 232 | } |
@@ -231,7 +263,7 @@ static int ircomm_tty_startup(struct ircomm_tty_cb *self) | |||
231 | 263 | ||
232 | return 0; | 264 | return 0; |
233 | err: | 265 | err: |
234 | clear_bit(ASYNC_B_INITIALIZED, &self->flags); | 266 | clear_bit(ASYNCB_INITIALIZED, &self->port.flags); |
235 | return ret; | 267 | return ret; |
236 | } | 268 | } |
237 | 269 | ||
@@ -242,72 +274,62 @@ err: | |||
242 | * | 274 | * |
243 | */ | 275 | */ |
244 | static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self, | 276 | static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self, |
245 | struct file *filp) | 277 | struct tty_struct *tty, struct file *filp) |
246 | { | 278 | { |
279 | struct tty_port *port = &self->port; | ||
247 | DECLARE_WAITQUEUE(wait, current); | 280 | DECLARE_WAITQUEUE(wait, current); |
248 | int retval; | 281 | int retval; |
249 | int do_clocal = 0, extra_count = 0; | 282 | int do_clocal = 0, extra_count = 0; |
250 | unsigned long flags; | 283 | unsigned long flags; |
251 | struct tty_struct *tty; | ||
252 | 284 | ||
253 | IRDA_DEBUG(2, "%s()\n", __func__ ); | 285 | IRDA_DEBUG(2, "%s()\n", __func__ ); |
254 | 286 | ||
255 | tty = self->tty; | ||
256 | |||
257 | /* | 287 | /* |
258 | * If non-blocking mode is set, or the port is not enabled, | 288 | * If non-blocking mode is set, or the port is not enabled, |
259 | * then make the check up front and then exit. | 289 | * then make the check up front and then exit. |
260 | */ | 290 | */ |
261 | if (filp->f_flags & O_NONBLOCK || tty->flags & (1 << TTY_IO_ERROR)){ | 291 | if (filp->f_flags & O_NONBLOCK || tty->flags & (1 << TTY_IO_ERROR)){ |
262 | /* nonblock mode is set or port is not enabled */ | 292 | /* nonblock mode is set or port is not enabled */ |
263 | self->flags |= ASYNC_NORMAL_ACTIVE; | 293 | port->flags |= ASYNC_NORMAL_ACTIVE; |
264 | IRDA_DEBUG(1, "%s(), O_NONBLOCK requested!\n", __func__ ); | 294 | IRDA_DEBUG(1, "%s(), O_NONBLOCK requested!\n", __func__ ); |
265 | return 0; | 295 | return 0; |
266 | } | 296 | } |
267 | 297 | ||
268 | if (tty->termios->c_cflag & CLOCAL) { | 298 | if (tty->termios.c_cflag & CLOCAL) { |
269 | IRDA_DEBUG(1, "%s(), doing CLOCAL!\n", __func__ ); | 299 | IRDA_DEBUG(1, "%s(), doing CLOCAL!\n", __func__ ); |
270 | do_clocal = 1; | 300 | do_clocal = 1; |
271 | } | 301 | } |
272 | 302 | ||
273 | /* Wait for carrier detect and the line to become | 303 | /* Wait for carrier detect and the line to become |
274 | * free (i.e., not in use by the callout). While we are in | 304 | * free (i.e., not in use by the callout). While we are in |
275 | * this loop, self->open_count is dropped by one, so that | 305 | * this loop, port->count is dropped by one, so that |
276 | * mgsl_close() knows when to free things. We restore it upon | 306 | * mgsl_close() knows when to free things. We restore it upon |
277 | * exit, either normal or abnormal. | 307 | * exit, either normal or abnormal. |
278 | */ | 308 | */ |
279 | 309 | ||
280 | retval = 0; | 310 | retval = 0; |
281 | add_wait_queue(&self->open_wait, &wait); | 311 | add_wait_queue(&port->open_wait, &wait); |
282 | 312 | ||
283 | IRDA_DEBUG(2, "%s(%d):block_til_ready before block on %s open_count=%d\n", | 313 | IRDA_DEBUG(2, "%s(%d):block_til_ready before block on %s open_count=%d\n", |
284 | __FILE__,__LINE__, tty->driver->name, self->open_count ); | 314 | __FILE__, __LINE__, tty->driver->name, port->count); |
285 | 315 | ||
286 | /* As far as I can see, we protect open_count - Jean II */ | 316 | spin_lock_irqsave(&port->lock, flags); |
287 | spin_lock_irqsave(&self->spinlock, flags); | ||
288 | if (!tty_hung_up_p(filp)) { | 317 | if (!tty_hung_up_p(filp)) { |
289 | extra_count = 1; | 318 | extra_count = 1; |
290 | self->open_count--; | 319 | port->count--; |
291 | } | 320 | } |
292 | spin_unlock_irqrestore(&self->spinlock, flags); | 321 | spin_unlock_irqrestore(&port->lock, flags); |
293 | self->blocked_open++; | 322 | port->blocked_open++; |
294 | 323 | ||
295 | while (1) { | 324 | while (1) { |
296 | if (tty->termios->c_cflag & CBAUD) { | 325 | if (tty->termios.c_cflag & CBAUD) |
297 | /* Here, we use to lock those two guys, but | 326 | tty_port_raise_dtr_rts(port); |
298 | * as ircomm_param_request() does it itself, | ||
299 | * I don't see the point (and I see the deadlock). | ||
300 | * Jean II */ | ||
301 | self->settings.dte |= IRCOMM_RTS + IRCOMM_DTR; | ||
302 | |||
303 | ircomm_param_request(self, IRCOMM_DTE, TRUE); | ||
304 | } | ||
305 | 327 | ||
306 | current->state = TASK_INTERRUPTIBLE; | 328 | current->state = TASK_INTERRUPTIBLE; |
307 | 329 | ||
308 | if (tty_hung_up_p(filp) || | 330 | if (tty_hung_up_p(filp) || |
309 | !test_bit(ASYNC_B_INITIALIZED, &self->flags)) { | 331 | !test_bit(ASYNCB_INITIALIZED, &port->flags)) { |
310 | retval = (self->flags & ASYNC_HUP_NOTIFY) ? | 332 | retval = (port->flags & ASYNC_HUP_NOTIFY) ? |
311 | -EAGAIN : -ERESTARTSYS; | 333 | -EAGAIN : -ERESTARTSYS; |
312 | break; | 334 | break; |
313 | } | 335 | } |
@@ -317,8 +339,8 @@ static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self, | |||
317 | * specified, we cannot return before the IrCOMM link is | 339 | * specified, we cannot return before the IrCOMM link is |
318 | * ready | 340 | * ready |
319 | */ | 341 | */ |
320 | if (!test_bit(ASYNC_B_CLOSING, &self->flags) && | 342 | if (!test_bit(ASYNCB_CLOSING, &port->flags) && |
321 | (do_clocal || (self->settings.dce & IRCOMM_CD)) && | 343 | (do_clocal || tty_port_carrier_raised(port)) && |
322 | self->state == IRCOMM_TTY_READY) | 344 | self->state == IRCOMM_TTY_READY) |
323 | { | 345 | { |
324 | break; | 346 | break; |
@@ -330,46 +352,36 @@ static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self, | |||
330 | } | 352 | } |
331 | 353 | ||
332 | IRDA_DEBUG(1, "%s(%d):block_til_ready blocking on %s open_count=%d\n", | 354 | IRDA_DEBUG(1, "%s(%d):block_til_ready blocking on %s open_count=%d\n", |
333 | __FILE__,__LINE__, tty->driver->name, self->open_count ); | 355 | __FILE__, __LINE__, tty->driver->name, port->count); |
334 | 356 | ||
335 | schedule(); | 357 | schedule(); |
336 | } | 358 | } |
337 | 359 | ||
338 | __set_current_state(TASK_RUNNING); | 360 | __set_current_state(TASK_RUNNING); |
339 | remove_wait_queue(&self->open_wait, &wait); | 361 | remove_wait_queue(&port->open_wait, &wait); |
340 | 362 | ||
341 | if (extra_count) { | 363 | if (extra_count) { |
342 | /* ++ is not atomic, so this should be protected - Jean II */ | 364 | /* ++ is not atomic, so this should be protected - Jean II */ |
343 | spin_lock_irqsave(&self->spinlock, flags); | 365 | spin_lock_irqsave(&port->lock, flags); |
344 | self->open_count++; | 366 | port->count++; |
345 | spin_unlock_irqrestore(&self->spinlock, flags); | 367 | spin_unlock_irqrestore(&port->lock, flags); |
346 | } | 368 | } |
347 | self->blocked_open--; | 369 | port->blocked_open--; |
348 | 370 | ||
349 | IRDA_DEBUG(1, "%s(%d):block_til_ready after blocking on %s open_count=%d\n", | 371 | IRDA_DEBUG(1, "%s(%d):block_til_ready after blocking on %s open_count=%d\n", |
350 | __FILE__,__LINE__, tty->driver->name, self->open_count); | 372 | __FILE__, __LINE__, tty->driver->name, port->count); |
351 | 373 | ||
352 | if (!retval) | 374 | if (!retval) |
353 | self->flags |= ASYNC_NORMAL_ACTIVE; | 375 | port->flags |= ASYNC_NORMAL_ACTIVE; |
354 | 376 | ||
355 | return retval; | 377 | return retval; |
356 | } | 378 | } |
357 | 379 | ||
358 | /* | 380 | |
359 | * Function ircomm_tty_open (tty, filp) | 381 | static int ircomm_tty_install(struct tty_driver *driver, struct tty_struct *tty) |
360 | * | ||
361 | * This routine is called when a particular tty device is opened. This | ||
362 | * routine is mandatory; if this routine is not filled in, the attempted | ||
363 | * open will fail with ENODEV. | ||
364 | */ | ||
365 | static int ircomm_tty_open(struct tty_struct *tty, struct file *filp) | ||
366 | { | 382 | { |
367 | struct ircomm_tty_cb *self; | 383 | struct ircomm_tty_cb *self; |
368 | unsigned int line = tty->index; | 384 | unsigned int line = tty->index; |
369 | unsigned long flags; | ||
370 | int ret; | ||
371 | |||
372 | IRDA_DEBUG(2, "%s()\n", __func__ ); | ||
373 | 385 | ||
374 | /* Check if instance already exists */ | 386 | /* Check if instance already exists */ |
375 | self = hashbin_lock_find(ircomm_tty, line, NULL); | 387 | self = hashbin_lock_find(ircomm_tty, line, NULL); |
@@ -381,6 +393,8 @@ static int ircomm_tty_open(struct tty_struct *tty, struct file *filp) | |||
381 | return -ENOMEM; | 393 | return -ENOMEM; |
382 | } | 394 | } |
383 | 395 | ||
396 | tty_port_init(&self->port); | ||
397 | self->port.ops = &ircomm_port_ops; | ||
384 | self->magic = IRCOMM_TTY_MAGIC; | 398 | self->magic = IRCOMM_TTY_MAGIC; |
385 | self->flow = FLOW_STOP; | 399 | self->flow = FLOW_STOP; |
386 | 400 | ||
@@ -388,13 +402,9 @@ static int ircomm_tty_open(struct tty_struct *tty, struct file *filp) | |||
388 | INIT_WORK(&self->tqueue, ircomm_tty_do_softint); | 402 | INIT_WORK(&self->tqueue, ircomm_tty_do_softint); |
389 | self->max_header_size = IRCOMM_TTY_HDR_UNINITIALISED; | 403 | self->max_header_size = IRCOMM_TTY_HDR_UNINITIALISED; |
390 | self->max_data_size = IRCOMM_TTY_DATA_UNINITIALISED; | 404 | self->max_data_size = IRCOMM_TTY_DATA_UNINITIALISED; |
391 | self->close_delay = 5*HZ/10; | ||
392 | self->closing_wait = 30*HZ; | ||
393 | 405 | ||
394 | /* Init some important stuff */ | 406 | /* Init some important stuff */ |
395 | init_timer(&self->watchdog_timer); | 407 | init_timer(&self->watchdog_timer); |
396 | init_waitqueue_head(&self->open_wait); | ||
397 | init_waitqueue_head(&self->close_wait); | ||
398 | spin_lock_init(&self->spinlock); | 408 | spin_lock_init(&self->spinlock); |
399 | 409 | ||
400 | /* | 410 | /* |
@@ -404,31 +414,48 @@ static int ircomm_tty_open(struct tty_struct *tty, struct file *filp) | |||
404 | * | 414 | * |
405 | * Note this is completely usafe and doesn't work properly | 415 | * Note this is completely usafe and doesn't work properly |
406 | */ | 416 | */ |
407 | tty->termios->c_iflag = 0; | 417 | tty->termios.c_iflag = 0; |
408 | tty->termios->c_oflag = 0; | 418 | tty->termios.c_oflag = 0; |
409 | 419 | ||
410 | /* Insert into hash */ | 420 | /* Insert into hash */ |
411 | hashbin_insert(ircomm_tty, (irda_queue_t *) self, line, NULL); | 421 | hashbin_insert(ircomm_tty, (irda_queue_t *) self, line, NULL); |
412 | } | 422 | } |
413 | /* ++ is not atomic, so this should be protected - Jean II */ | ||
414 | spin_lock_irqsave(&self->spinlock, flags); | ||
415 | self->open_count++; | ||
416 | 423 | ||
417 | tty->driver_data = self; | 424 | return tty_port_install(&self->port, driver, tty); |
418 | self->tty = tty; | 425 | } |
419 | spin_unlock_irqrestore(&self->spinlock, flags); | 426 | |
427 | /* | ||
428 | * Function ircomm_tty_open (tty, filp) | ||
429 | * | ||
430 | * This routine is called when a particular tty device is opened. This | ||
431 | * routine is mandatory; if this routine is not filled in, the attempted | ||
432 | * open will fail with ENODEV. | ||
433 | */ | ||
434 | static int ircomm_tty_open(struct tty_struct *tty, struct file *filp) | ||
435 | { | ||
436 | struct ircomm_tty_cb *self = tty->driver_data; | ||
437 | unsigned long flags; | ||
438 | int ret; | ||
439 | |||
440 | IRDA_DEBUG(2, "%s()\n", __func__ ); | ||
441 | |||
442 | /* ++ is not atomic, so this should be protected - Jean II */ | ||
443 | spin_lock_irqsave(&self->port.lock, flags); | ||
444 | self->port.count++; | ||
445 | spin_unlock_irqrestore(&self->port.lock, flags); | ||
446 | tty_port_tty_set(&self->port, tty); | ||
420 | 447 | ||
421 | IRDA_DEBUG(1, "%s(), %s%d, count = %d\n", __func__ , tty->driver->name, | 448 | IRDA_DEBUG(1, "%s(), %s%d, count = %d\n", __func__ , tty->driver->name, |
422 | self->line, self->open_count); | 449 | self->line, self->port.count); |
423 | 450 | ||
424 | /* Not really used by us, but lets do it anyway */ | 451 | /* Not really used by us, but lets do it anyway */ |
425 | self->tty->low_latency = (self->flags & ASYNC_LOW_LATENCY) ? 1 : 0; | 452 | tty->low_latency = (self->port.flags & ASYNC_LOW_LATENCY) ? 1 : 0; |
426 | 453 | ||
427 | /* | 454 | /* |
428 | * If the port is the middle of closing, bail out now | 455 | * If the port is the middle of closing, bail out now |
429 | */ | 456 | */ |
430 | if (tty_hung_up_p(filp) || | 457 | if (tty_hung_up_p(filp) || |
431 | test_bit(ASYNC_B_CLOSING, &self->flags)) { | 458 | test_bit(ASYNCB_CLOSING, &self->port.flags)) { |
432 | 459 | ||
433 | /* Hm, why are we blocking on ASYNC_CLOSING if we | 460 | /* Hm, why are we blocking on ASYNC_CLOSING if we |
434 | * do return -EAGAIN/-ERESTARTSYS below anyway? | 461 | * do return -EAGAIN/-ERESTARTSYS below anyway? |
@@ -438,14 +465,15 @@ static int ircomm_tty_open(struct tty_struct *tty, struct file *filp) | |||
438 | * probably better sleep uninterruptible? | 465 | * probably better sleep uninterruptible? |
439 | */ | 466 | */ |
440 | 467 | ||
441 | if (wait_event_interruptible(self->close_wait, !test_bit(ASYNC_B_CLOSING, &self->flags))) { | 468 | if (wait_event_interruptible(self->port.close_wait, |
469 | !test_bit(ASYNCB_CLOSING, &self->port.flags))) { | ||
442 | IRDA_WARNING("%s - got signal while blocking on ASYNC_CLOSING!\n", | 470 | IRDA_WARNING("%s - got signal while blocking on ASYNC_CLOSING!\n", |
443 | __func__); | 471 | __func__); |
444 | return -ERESTARTSYS; | 472 | return -ERESTARTSYS; |
445 | } | 473 | } |
446 | 474 | ||
447 | #ifdef SERIAL_DO_RESTART | 475 | #ifdef SERIAL_DO_RESTART |
448 | return (self->flags & ASYNC_HUP_NOTIFY) ? | 476 | return (self->port.flags & ASYNC_HUP_NOTIFY) ? |
449 | -EAGAIN : -ERESTARTSYS; | 477 | -EAGAIN : -ERESTARTSYS; |
450 | #else | 478 | #else |
451 | return -EAGAIN; | 479 | return -EAGAIN; |
@@ -453,7 +481,7 @@ static int ircomm_tty_open(struct tty_struct *tty, struct file *filp) | |||
453 | } | 481 | } |
454 | 482 | ||
455 | /* Check if this is a "normal" ircomm device, or an irlpt device */ | 483 | /* Check if this is a "normal" ircomm device, or an irlpt device */ |
456 | if (line < 0x10) { | 484 | if (self->line < 0x10) { |
457 | self->service_type = IRCOMM_3_WIRE | IRCOMM_9_WIRE; | 485 | self->service_type = IRCOMM_3_WIRE | IRCOMM_9_WIRE; |
458 | self->settings.service_type = IRCOMM_9_WIRE; /* 9 wire as default */ | 486 | self->settings.service_type = IRCOMM_9_WIRE; /* 9 wire as default */ |
459 | /* Jan Kiszka -> add DSR/RI -> Conform to IrCOMM spec */ | 487 | /* Jan Kiszka -> add DSR/RI -> Conform to IrCOMM spec */ |
@@ -469,7 +497,7 @@ static int ircomm_tty_open(struct tty_struct *tty, struct file *filp) | |||
469 | if (ret) | 497 | if (ret) |
470 | return ret; | 498 | return ret; |
471 | 499 | ||
472 | ret = ircomm_tty_block_til_ready(self, filp); | 500 | ret = ircomm_tty_block_til_ready(self, tty, filp); |
473 | if (ret) { | 501 | if (ret) { |
474 | IRDA_DEBUG(2, | 502 | IRDA_DEBUG(2, |
475 | "%s(), returning after block_til_ready with %d\n", __func__ , | 503 | "%s(), returning after block_til_ready with %d\n", __func__ , |
@@ -489,81 +517,22 @@ static int ircomm_tty_open(struct tty_struct *tty, struct file *filp) | |||
489 | static void ircomm_tty_close(struct tty_struct *tty, struct file *filp) | 517 | static void ircomm_tty_close(struct tty_struct *tty, struct file *filp) |
490 | { | 518 | { |
491 | struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data; | 519 | struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data; |
492 | unsigned long flags; | 520 | struct tty_port *port = &self->port; |
493 | 521 | ||
494 | IRDA_DEBUG(0, "%s()\n", __func__ ); | 522 | IRDA_DEBUG(0, "%s()\n", __func__ ); |
495 | 523 | ||
496 | IRDA_ASSERT(self != NULL, return;); | 524 | IRDA_ASSERT(self != NULL, return;); |
497 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); | 525 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); |
498 | 526 | ||
499 | spin_lock_irqsave(&self->spinlock, flags); | 527 | if (tty_port_close_start(port, tty, filp) == 0) |
500 | |||
501 | if (tty_hung_up_p(filp)) { | ||
502 | spin_unlock_irqrestore(&self->spinlock, flags); | ||
503 | |||
504 | IRDA_DEBUG(0, "%s(), returning 1\n", __func__ ); | ||
505 | return; | ||
506 | } | ||
507 | |||
508 | if ((tty->count == 1) && (self->open_count != 1)) { | ||
509 | /* | ||
510 | * Uh, oh. tty->count is 1, which means that the tty | ||
511 | * structure will be freed. state->count should always | ||
512 | * be one in these conditions. If it's greater than | ||
513 | * one, we've got real problems, since it means the | ||
514 | * serial port won't be shutdown. | ||
515 | */ | ||
516 | IRDA_DEBUG(0, "%s(), bad serial port count; " | ||
517 | "tty->count is 1, state->count is %d\n", __func__ , | ||
518 | self->open_count); | ||
519 | self->open_count = 1; | ||
520 | } | ||
521 | |||
522 | if (--self->open_count < 0) { | ||
523 | IRDA_ERROR("%s(), bad serial port count for ttys%d: %d\n", | ||
524 | __func__, self->line, self->open_count); | ||
525 | self->open_count = 0; | ||
526 | } | ||
527 | if (self->open_count) { | ||
528 | spin_unlock_irqrestore(&self->spinlock, flags); | ||
529 | |||
530 | IRDA_DEBUG(0, "%s(), open count > 0\n", __func__ ); | ||
531 | return; | 528 | return; |
532 | } | ||
533 | |||
534 | /* Hum... Should be test_and_set_bit ??? - Jean II */ | ||
535 | set_bit(ASYNC_B_CLOSING, &self->flags); | ||
536 | |||
537 | /* We need to unlock here (we were unlocking at the end of this | ||
538 | * function), because tty_wait_until_sent() may schedule. | ||
539 | * I don't know if the rest should be protected somehow, | ||
540 | * so someone should check. - Jean II */ | ||
541 | spin_unlock_irqrestore(&self->spinlock, flags); | ||
542 | |||
543 | /* | ||
544 | * Now we wait for the transmit buffer to clear; and we notify | ||
545 | * the line discipline to only process XON/XOFF characters. | ||
546 | */ | ||
547 | tty->closing = 1; | ||
548 | if (self->closing_wait != ASYNC_CLOSING_WAIT_NONE) | ||
549 | tty_wait_until_sent_from_close(tty, self->closing_wait); | ||
550 | 529 | ||
551 | ircomm_tty_shutdown(self); | 530 | ircomm_tty_shutdown(self); |
552 | 531 | ||
553 | tty_driver_flush_buffer(tty); | 532 | tty_driver_flush_buffer(tty); |
554 | tty_ldisc_flush(tty); | ||
555 | |||
556 | tty->closing = 0; | ||
557 | self->tty = NULL; | ||
558 | 533 | ||
559 | if (self->blocked_open) { | 534 | tty_port_close_end(port, tty); |
560 | if (self->close_delay) | 535 | tty_port_tty_set(port, NULL); |
561 | schedule_timeout_interruptible(self->close_delay); | ||
562 | wake_up_interruptible(&self->open_wait); | ||
563 | } | ||
564 | |||
565 | self->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); | ||
566 | wake_up_interruptible(&self->close_wait); | ||
567 | } | 536 | } |
568 | 537 | ||
569 | /* | 538 | /* |
@@ -606,7 +575,7 @@ static void ircomm_tty_do_softint(struct work_struct *work) | |||
606 | if (!self || self->magic != IRCOMM_TTY_MAGIC) | 575 | if (!self || self->magic != IRCOMM_TTY_MAGIC) |
607 | return; | 576 | return; |
608 | 577 | ||
609 | tty = self->tty; | 578 | tty = tty_port_tty_get(&self->port); |
610 | if (!tty) | 579 | if (!tty) |
611 | return; | 580 | return; |
612 | 581 | ||
@@ -627,7 +596,7 @@ static void ircomm_tty_do_softint(struct work_struct *work) | |||
627 | } | 596 | } |
628 | 597 | ||
629 | if (tty->hw_stopped) | 598 | if (tty->hw_stopped) |
630 | return; | 599 | goto put; |
631 | 600 | ||
632 | /* Unlink transmit buffer */ | 601 | /* Unlink transmit buffer */ |
633 | spin_lock_irqsave(&self->spinlock, flags); | 602 | spin_lock_irqsave(&self->spinlock, flags); |
@@ -646,6 +615,8 @@ static void ircomm_tty_do_softint(struct work_struct *work) | |||
646 | 615 | ||
647 | /* Check if user (still) wants to be waken up */ | 616 | /* Check if user (still) wants to be waken up */ |
648 | tty_wakeup(tty); | 617 | tty_wakeup(tty); |
618 | put: | ||
619 | tty_kref_put(tty); | ||
649 | } | 620 | } |
650 | 621 | ||
651 | /* | 622 | /* |
@@ -880,7 +851,7 @@ static void ircomm_tty_throttle(struct tty_struct *tty) | |||
880 | ircomm_tty_send_xchar(tty, STOP_CHAR(tty)); | 851 | ircomm_tty_send_xchar(tty, STOP_CHAR(tty)); |
881 | 852 | ||
882 | /* Hardware flow control? */ | 853 | /* Hardware flow control? */ |
883 | if (tty->termios->c_cflag & CRTSCTS) { | 854 | if (tty->termios.c_cflag & CRTSCTS) { |
884 | self->settings.dte &= ~IRCOMM_RTS; | 855 | self->settings.dte &= ~IRCOMM_RTS; |
885 | self->settings.dte |= IRCOMM_DELTA_RTS; | 856 | self->settings.dte |= IRCOMM_DELTA_RTS; |
886 | 857 | ||
@@ -912,7 +883,7 @@ static void ircomm_tty_unthrottle(struct tty_struct *tty) | |||
912 | } | 883 | } |
913 | 884 | ||
914 | /* Using hardware flow control? */ | 885 | /* Using hardware flow control? */ |
915 | if (tty->termios->c_cflag & CRTSCTS) { | 886 | if (tty->termios.c_cflag & CRTSCTS) { |
916 | self->settings.dte |= (IRCOMM_RTS|IRCOMM_DELTA_RTS); | 887 | self->settings.dte |= (IRCOMM_RTS|IRCOMM_DELTA_RTS); |
917 | 888 | ||
918 | ircomm_param_request(self, IRCOMM_DTE, TRUE); | 889 | ircomm_param_request(self, IRCOMM_DTE, TRUE); |
@@ -955,7 +926,7 @@ static void ircomm_tty_shutdown(struct ircomm_tty_cb *self) | |||
955 | 926 | ||
956 | IRDA_DEBUG(0, "%s()\n", __func__ ); | 927 | IRDA_DEBUG(0, "%s()\n", __func__ ); |
957 | 928 | ||
958 | if (!test_and_clear_bit(ASYNC_B_INITIALIZED, &self->flags)) | 929 | if (!test_and_clear_bit(ASYNCB_INITIALIZED, &self->port.flags)) |
959 | return; | 930 | return; |
960 | 931 | ||
961 | ircomm_tty_detach_cable(self); | 932 | ircomm_tty_detach_cable(self); |
@@ -994,6 +965,7 @@ static void ircomm_tty_shutdown(struct ircomm_tty_cb *self) | |||
994 | static void ircomm_tty_hangup(struct tty_struct *tty) | 965 | static void ircomm_tty_hangup(struct tty_struct *tty) |
995 | { | 966 | { |
996 | struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data; | 967 | struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data; |
968 | struct tty_port *port = &self->port; | ||
997 | unsigned long flags; | 969 | unsigned long flags; |
998 | 970 | ||
999 | IRDA_DEBUG(0, "%s()\n", __func__ ); | 971 | IRDA_DEBUG(0, "%s()\n", __func__ ); |
@@ -1004,14 +976,17 @@ static void ircomm_tty_hangup(struct tty_struct *tty) | |||
1004 | /* ircomm_tty_flush_buffer(tty); */ | 976 | /* ircomm_tty_flush_buffer(tty); */ |
1005 | ircomm_tty_shutdown(self); | 977 | ircomm_tty_shutdown(self); |
1006 | 978 | ||
1007 | /* I guess we need to lock here - Jean II */ | 979 | spin_lock_irqsave(&port->lock, flags); |
1008 | spin_lock_irqsave(&self->spinlock, flags); | 980 | port->flags &= ~ASYNC_NORMAL_ACTIVE; |
1009 | self->flags &= ~ASYNC_NORMAL_ACTIVE; | 981 | if (port->tty) { |
1010 | self->tty = NULL; | 982 | set_bit(TTY_IO_ERROR, &port->tty->flags); |
1011 | self->open_count = 0; | 983 | tty_kref_put(port->tty); |
1012 | spin_unlock_irqrestore(&self->spinlock, flags); | 984 | } |
985 | port->tty = NULL; | ||
986 | port->count = 0; | ||
987 | spin_unlock_irqrestore(&port->lock, flags); | ||
1013 | 988 | ||
1014 | wake_up_interruptible(&self->open_wait); | 989 | wake_up_interruptible(&port->open_wait); |
1015 | } | 990 | } |
1016 | 991 | ||
1017 | /* | 992 | /* |
@@ -1071,20 +1046,20 @@ void ircomm_tty_check_modem_status(struct ircomm_tty_cb *self) | |||
1071 | IRDA_ASSERT(self != NULL, return;); | 1046 | IRDA_ASSERT(self != NULL, return;); |
1072 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); | 1047 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); |
1073 | 1048 | ||
1074 | tty = self->tty; | 1049 | tty = tty_port_tty_get(&self->port); |
1075 | 1050 | ||
1076 | status = self->settings.dce; | 1051 | status = self->settings.dce; |
1077 | 1052 | ||
1078 | if (status & IRCOMM_DCE_DELTA_ANY) { | 1053 | if (status & IRCOMM_DCE_DELTA_ANY) { |
1079 | /*wake_up_interruptible(&self->delta_msr_wait);*/ | 1054 | /*wake_up_interruptible(&self->delta_msr_wait);*/ |
1080 | } | 1055 | } |
1081 | if ((self->flags & ASYNC_CHECK_CD) && (status & IRCOMM_DELTA_CD)) { | 1056 | if ((self->port.flags & ASYNC_CHECK_CD) && (status & IRCOMM_DELTA_CD)) { |
1082 | IRDA_DEBUG(2, | 1057 | IRDA_DEBUG(2, |
1083 | "%s(), ircomm%d CD now %s...\n", __func__ , self->line, | 1058 | "%s(), ircomm%d CD now %s...\n", __func__ , self->line, |
1084 | (status & IRCOMM_CD) ? "on" : "off"); | 1059 | (status & IRCOMM_CD) ? "on" : "off"); |
1085 | 1060 | ||
1086 | if (status & IRCOMM_CD) { | 1061 | if (status & IRCOMM_CD) { |
1087 | wake_up_interruptible(&self->open_wait); | 1062 | wake_up_interruptible(&self->port.open_wait); |
1088 | } else { | 1063 | } else { |
1089 | IRDA_DEBUG(2, | 1064 | IRDA_DEBUG(2, |
1090 | "%s(), Doing serial hangup..\n", __func__ ); | 1065 | "%s(), Doing serial hangup..\n", __func__ ); |
@@ -1092,10 +1067,10 @@ void ircomm_tty_check_modem_status(struct ircomm_tty_cb *self) | |||
1092 | tty_hangup(tty); | 1067 | tty_hangup(tty); |
1093 | 1068 | ||
1094 | /* Hangup will remote the tty, so better break out */ | 1069 | /* Hangup will remote the tty, so better break out */ |
1095 | return; | 1070 | goto put; |
1096 | } | 1071 | } |
1097 | } | 1072 | } |
1098 | if (self->flags & ASYNC_CTS_FLOW) { | 1073 | if (tty && tty_port_cts_enabled(&self->port)) { |
1099 | if (tty->hw_stopped) { | 1074 | if (tty->hw_stopped) { |
1100 | if (status & IRCOMM_CTS) { | 1075 | if (status & IRCOMM_CTS) { |
1101 | IRDA_DEBUG(2, | 1076 | IRDA_DEBUG(2, |
@@ -1103,10 +1078,10 @@ void ircomm_tty_check_modem_status(struct ircomm_tty_cb *self) | |||
1103 | tty->hw_stopped = 0; | 1078 | tty->hw_stopped = 0; |
1104 | 1079 | ||
1105 | /* Wake up processes blocked on open */ | 1080 | /* Wake up processes blocked on open */ |
1106 | wake_up_interruptible(&self->open_wait); | 1081 | wake_up_interruptible(&self->port.open_wait); |
1107 | 1082 | ||
1108 | schedule_work(&self->tqueue); | 1083 | schedule_work(&self->tqueue); |
1109 | return; | 1084 | goto put; |
1110 | } | 1085 | } |
1111 | } else { | 1086 | } else { |
1112 | if (!(status & IRCOMM_CTS)) { | 1087 | if (!(status & IRCOMM_CTS)) { |
@@ -1116,6 +1091,8 @@ void ircomm_tty_check_modem_status(struct ircomm_tty_cb *self) | |||
1116 | } | 1091 | } |
1117 | } | 1092 | } |
1118 | } | 1093 | } |
1094 | put: | ||
1095 | tty_kref_put(tty); | ||
1119 | } | 1096 | } |
1120 | 1097 | ||
1121 | /* | 1098 | /* |
@@ -1128,6 +1105,7 @@ static int ircomm_tty_data_indication(void *instance, void *sap, | |||
1128 | struct sk_buff *skb) | 1105 | struct sk_buff *skb) |
1129 | { | 1106 | { |
1130 | struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance; | 1107 | struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance; |
1108 | struct tty_struct *tty; | ||
1131 | 1109 | ||
1132 | IRDA_DEBUG(2, "%s()\n", __func__ ); | 1110 | IRDA_DEBUG(2, "%s()\n", __func__ ); |
1133 | 1111 | ||
@@ -1135,7 +1113,8 @@ static int ircomm_tty_data_indication(void *instance, void *sap, | |||
1135 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;); | 1113 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;); |
1136 | IRDA_ASSERT(skb != NULL, return -1;); | 1114 | IRDA_ASSERT(skb != NULL, return -1;); |
1137 | 1115 | ||
1138 | if (!self->tty) { | 1116 | tty = tty_port_tty_get(&self->port); |
1117 | if (!tty) { | ||
1139 | IRDA_DEBUG(0, "%s(), no tty!\n", __func__ ); | 1118 | IRDA_DEBUG(0, "%s(), no tty!\n", __func__ ); |
1140 | return 0; | 1119 | return 0; |
1141 | } | 1120 | } |
@@ -1146,7 +1125,7 @@ static int ircomm_tty_data_indication(void *instance, void *sap, | |||
1146 | * Devices like WinCE can do this, and since they don't send any | 1125 | * Devices like WinCE can do this, and since they don't send any |
1147 | * params, we can just as well declare the hardware for running. | 1126 | * params, we can just as well declare the hardware for running. |
1148 | */ | 1127 | */ |
1149 | if (self->tty->hw_stopped && (self->flow == FLOW_START)) { | 1128 | if (tty->hw_stopped && (self->flow == FLOW_START)) { |
1150 | IRDA_DEBUG(0, "%s(), polling for line settings!\n", __func__ ); | 1129 | IRDA_DEBUG(0, "%s(), polling for line settings!\n", __func__ ); |
1151 | ircomm_param_request(self, IRCOMM_POLL, TRUE); | 1130 | ircomm_param_request(self, IRCOMM_POLL, TRUE); |
1152 | 1131 | ||
@@ -1159,8 +1138,9 @@ static int ircomm_tty_data_indication(void *instance, void *sap, | |||
1159 | * Use flip buffer functions since the code may be called from interrupt | 1138 | * Use flip buffer functions since the code may be called from interrupt |
1160 | * context | 1139 | * context |
1161 | */ | 1140 | */ |
1162 | tty_insert_flip_string(self->tty, skb->data, skb->len); | 1141 | tty_insert_flip_string(tty, skb->data, skb->len); |
1163 | tty_flip_buffer_push(self->tty); | 1142 | tty_flip_buffer_push(tty); |
1143 | tty_kref_put(tty); | ||
1164 | 1144 | ||
1165 | /* No need to kfree_skb - see ircomm_ttp_data_indication() */ | 1145 | /* No need to kfree_skb - see ircomm_ttp_data_indication() */ |
1166 | 1146 | ||
@@ -1211,12 +1191,13 @@ static void ircomm_tty_flow_indication(void *instance, void *sap, | |||
1211 | IRDA_ASSERT(self != NULL, return;); | 1191 | IRDA_ASSERT(self != NULL, return;); |
1212 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); | 1192 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); |
1213 | 1193 | ||
1214 | tty = self->tty; | 1194 | tty = tty_port_tty_get(&self->port); |
1215 | 1195 | ||
1216 | switch (cmd) { | 1196 | switch (cmd) { |
1217 | case FLOW_START: | 1197 | case FLOW_START: |
1218 | IRDA_DEBUG(2, "%s(), hw start!\n", __func__ ); | 1198 | IRDA_DEBUG(2, "%s(), hw start!\n", __func__ ); |
1219 | tty->hw_stopped = 0; | 1199 | if (tty) |
1200 | tty->hw_stopped = 0; | ||
1220 | 1201 | ||
1221 | /* ircomm_tty_do_softint will take care of the rest */ | 1202 | /* ircomm_tty_do_softint will take care of the rest */ |
1222 | schedule_work(&self->tqueue); | 1203 | schedule_work(&self->tqueue); |
@@ -1224,15 +1205,19 @@ static void ircomm_tty_flow_indication(void *instance, void *sap, | |||
1224 | default: /* If we get here, something is very wrong, better stop */ | 1205 | default: /* If we get here, something is very wrong, better stop */ |
1225 | case FLOW_STOP: | 1206 | case FLOW_STOP: |
1226 | IRDA_DEBUG(2, "%s(), hw stopped!\n", __func__ ); | 1207 | IRDA_DEBUG(2, "%s(), hw stopped!\n", __func__ ); |
1227 | tty->hw_stopped = 1; | 1208 | if (tty) |
1209 | tty->hw_stopped = 1; | ||
1228 | break; | 1210 | break; |
1229 | } | 1211 | } |
1212 | |||
1213 | tty_kref_put(tty); | ||
1230 | self->flow = cmd; | 1214 | self->flow = cmd; |
1231 | } | 1215 | } |
1232 | 1216 | ||
1233 | #ifdef CONFIG_PROC_FS | 1217 | #ifdef CONFIG_PROC_FS |
1234 | static void ircomm_tty_line_info(struct ircomm_tty_cb *self, struct seq_file *m) | 1218 | static void ircomm_tty_line_info(struct ircomm_tty_cb *self, struct seq_file *m) |
1235 | { | 1219 | { |
1220 | struct tty_struct *tty; | ||
1236 | char sep; | 1221 | char sep; |
1237 | 1222 | ||
1238 | seq_printf(m, "State: %s\n", ircomm_tty_state[self->state]); | 1223 | seq_printf(m, "State: %s\n", ircomm_tty_state[self->state]); |
@@ -1328,40 +1313,43 @@ static void ircomm_tty_line_info(struct ircomm_tty_cb *self, struct seq_file *m) | |||
1328 | 1313 | ||
1329 | seq_puts(m, "Flags:"); | 1314 | seq_puts(m, "Flags:"); |
1330 | sep = ' '; | 1315 | sep = ' '; |
1331 | if (self->flags & ASYNC_CTS_FLOW) { | 1316 | if (tty_port_cts_enabled(&self->port)) { |
1332 | seq_printf(m, "%cASYNC_CTS_FLOW", sep); | 1317 | seq_printf(m, "%cASYNC_CTS_FLOW", sep); |
1333 | sep = '|'; | 1318 | sep = '|'; |
1334 | } | 1319 | } |
1335 | if (self->flags & ASYNC_CHECK_CD) { | 1320 | if (self->port.flags & ASYNC_CHECK_CD) { |
1336 | seq_printf(m, "%cASYNC_CHECK_CD", sep); | 1321 | seq_printf(m, "%cASYNC_CHECK_CD", sep); |
1337 | sep = '|'; | 1322 | sep = '|'; |
1338 | } | 1323 | } |
1339 | if (self->flags & ASYNC_INITIALIZED) { | 1324 | if (self->port.flags & ASYNC_INITIALIZED) { |
1340 | seq_printf(m, "%cASYNC_INITIALIZED", sep); | 1325 | seq_printf(m, "%cASYNC_INITIALIZED", sep); |
1341 | sep = '|'; | 1326 | sep = '|'; |
1342 | } | 1327 | } |
1343 | if (self->flags & ASYNC_LOW_LATENCY) { | 1328 | if (self->port.flags & ASYNC_LOW_LATENCY) { |
1344 | seq_printf(m, "%cASYNC_LOW_LATENCY", sep); | 1329 | seq_printf(m, "%cASYNC_LOW_LATENCY", sep); |
1345 | sep = '|'; | 1330 | sep = '|'; |
1346 | } | 1331 | } |
1347 | if (self->flags & ASYNC_CLOSING) { | 1332 | if (self->port.flags & ASYNC_CLOSING) { |
1348 | seq_printf(m, "%cASYNC_CLOSING", sep); | 1333 | seq_printf(m, "%cASYNC_CLOSING", sep); |
1349 | sep = '|'; | 1334 | sep = '|'; |
1350 | } | 1335 | } |
1351 | if (self->flags & ASYNC_NORMAL_ACTIVE) { | 1336 | if (self->port.flags & ASYNC_NORMAL_ACTIVE) { |
1352 | seq_printf(m, "%cASYNC_NORMAL_ACTIVE", sep); | 1337 | seq_printf(m, "%cASYNC_NORMAL_ACTIVE", sep); |
1353 | sep = '|'; | 1338 | sep = '|'; |
1354 | } | 1339 | } |
1355 | seq_putc(m, '\n'); | 1340 | seq_putc(m, '\n'); |
1356 | 1341 | ||
1357 | seq_printf(m, "Role: %s\n", self->client ? "client" : "server"); | 1342 | seq_printf(m, "Role: %s\n", self->client ? "client" : "server"); |
1358 | seq_printf(m, "Open count: %d\n", self->open_count); | 1343 | seq_printf(m, "Open count: %d\n", self->port.count); |
1359 | seq_printf(m, "Max data size: %d\n", self->max_data_size); | 1344 | seq_printf(m, "Max data size: %d\n", self->max_data_size); |
1360 | seq_printf(m, "Max header size: %d\n", self->max_header_size); | 1345 | seq_printf(m, "Max header size: %d\n", self->max_header_size); |
1361 | 1346 | ||
1362 | if (self->tty) | 1347 | tty = tty_port_tty_get(&self->port); |
1348 | if (tty) { | ||
1363 | seq_printf(m, "Hardware: %s\n", | 1349 | seq_printf(m, "Hardware: %s\n", |
1364 | self->tty->hw_stopped ? "Stopped" : "Running"); | 1350 | tty->hw_stopped ? "Stopped" : "Running"); |
1351 | tty_kref_put(tty); | ||
1352 | } | ||
1365 | } | 1353 | } |
1366 | 1354 | ||
1367 | static int ircomm_tty_proc_show(struct seq_file *m, void *v) | 1355 | static int ircomm_tty_proc_show(struct seq_file *m, void *v) |
diff --git a/net/irda/ircomm/ircomm_tty_attach.c b/net/irda/ircomm/ircomm_tty_attach.c index b65d66e0d817..edab393e0c82 100644 --- a/net/irda/ircomm/ircomm_tty_attach.c +++ b/net/irda/ircomm/ircomm_tty_attach.c | |||
@@ -130,6 +130,8 @@ static int (*state[])(struct ircomm_tty_cb *self, IRCOMM_TTY_EVENT event, | |||
130 | */ | 130 | */ |
131 | int ircomm_tty_attach_cable(struct ircomm_tty_cb *self) | 131 | int ircomm_tty_attach_cable(struct ircomm_tty_cb *self) |
132 | { | 132 | { |
133 | struct tty_struct *tty; | ||
134 | |||
133 | IRDA_DEBUG(0, "%s()\n", __func__ ); | 135 | IRDA_DEBUG(0, "%s()\n", __func__ ); |
134 | 136 | ||
135 | IRDA_ASSERT(self != NULL, return -1;); | 137 | IRDA_ASSERT(self != NULL, return -1;); |
@@ -142,7 +144,11 @@ int ircomm_tty_attach_cable(struct ircomm_tty_cb *self) | |||
142 | } | 144 | } |
143 | 145 | ||
144 | /* Make sure nobody tries to write before the link is up */ | 146 | /* Make sure nobody tries to write before the link is up */ |
145 | self->tty->hw_stopped = 1; | 147 | tty = tty_port_tty_get(&self->port); |
148 | if (tty) { | ||
149 | tty->hw_stopped = 1; | ||
150 | tty_kref_put(tty); | ||
151 | } | ||
146 | 152 | ||
147 | ircomm_tty_ias_register(self); | 153 | ircomm_tty_ias_register(self); |
148 | 154 | ||
@@ -398,23 +404,26 @@ void ircomm_tty_disconnect_indication(void *instance, void *sap, | |||
398 | struct sk_buff *skb) | 404 | struct sk_buff *skb) |
399 | { | 405 | { |
400 | struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance; | 406 | struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance; |
407 | struct tty_struct *tty; | ||
401 | 408 | ||
402 | IRDA_DEBUG(2, "%s()\n", __func__ ); | 409 | IRDA_DEBUG(2, "%s()\n", __func__ ); |
403 | 410 | ||
404 | IRDA_ASSERT(self != NULL, return;); | 411 | IRDA_ASSERT(self != NULL, return;); |
405 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); | 412 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); |
406 | 413 | ||
407 | if (!self->tty) | 414 | tty = tty_port_tty_get(&self->port); |
415 | if (!tty) | ||
408 | return; | 416 | return; |
409 | 417 | ||
410 | /* This will stop control data transfers */ | 418 | /* This will stop control data transfers */ |
411 | self->flow = FLOW_STOP; | 419 | self->flow = FLOW_STOP; |
412 | 420 | ||
413 | /* Stop data transfers */ | 421 | /* Stop data transfers */ |
414 | self->tty->hw_stopped = 1; | 422 | tty->hw_stopped = 1; |
415 | 423 | ||
416 | ircomm_tty_do_event(self, IRCOMM_TTY_DISCONNECT_INDICATION, NULL, | 424 | ircomm_tty_do_event(self, IRCOMM_TTY_DISCONNECT_INDICATION, NULL, |
417 | NULL); | 425 | NULL); |
426 | tty_kref_put(tty); | ||
418 | } | 427 | } |
419 | 428 | ||
420 | /* | 429 | /* |
@@ -550,12 +559,15 @@ void ircomm_tty_connect_indication(void *instance, void *sap, | |||
550 | */ | 559 | */ |
551 | void ircomm_tty_link_established(struct ircomm_tty_cb *self) | 560 | void ircomm_tty_link_established(struct ircomm_tty_cb *self) |
552 | { | 561 | { |
562 | struct tty_struct *tty; | ||
563 | |||
553 | IRDA_DEBUG(2, "%s()\n", __func__ ); | 564 | IRDA_DEBUG(2, "%s()\n", __func__ ); |
554 | 565 | ||
555 | IRDA_ASSERT(self != NULL, return;); | 566 | IRDA_ASSERT(self != NULL, return;); |
556 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); | 567 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); |
557 | 568 | ||
558 | if (!self->tty) | 569 | tty = tty_port_tty_get(&self->port); |
570 | if (!tty) | ||
559 | return; | 571 | return; |
560 | 572 | ||
561 | del_timer(&self->watchdog_timer); | 573 | del_timer(&self->watchdog_timer); |
@@ -566,19 +578,22 @@ void ircomm_tty_link_established(struct ircomm_tty_cb *self) | |||
566 | * will have to wait for the peer device (DCE) to raise the CTS | 578 | * will have to wait for the peer device (DCE) to raise the CTS |
567 | * line. | 579 | * line. |
568 | */ | 580 | */ |
569 | if ((self->flags & ASYNC_CTS_FLOW) && ((self->settings.dce & IRCOMM_CTS) == 0)) { | 581 | if (tty_port_cts_enabled(&self->port) && |
582 | ((self->settings.dce & IRCOMM_CTS) == 0)) { | ||
570 | IRDA_DEBUG(0, "%s(), waiting for CTS ...\n", __func__ ); | 583 | IRDA_DEBUG(0, "%s(), waiting for CTS ...\n", __func__ ); |
571 | return; | 584 | goto put; |
572 | } else { | 585 | } else { |
573 | IRDA_DEBUG(1, "%s(), starting hardware!\n", __func__ ); | 586 | IRDA_DEBUG(1, "%s(), starting hardware!\n", __func__ ); |
574 | 587 | ||
575 | self->tty->hw_stopped = 0; | 588 | tty->hw_stopped = 0; |
576 | 589 | ||
577 | /* Wake up processes blocked on open */ | 590 | /* Wake up processes blocked on open */ |
578 | wake_up_interruptible(&self->open_wait); | 591 | wake_up_interruptible(&self->port.open_wait); |
579 | } | 592 | } |
580 | 593 | ||
581 | schedule_work(&self->tqueue); | 594 | schedule_work(&self->tqueue); |
595 | put: | ||
596 | tty_kref_put(tty); | ||
582 | } | 597 | } |
583 | 598 | ||
584 | /* | 599 | /* |
@@ -977,14 +992,17 @@ static int ircomm_tty_state_ready(struct ircomm_tty_cb *self, | |||
977 | ircomm_tty_next_state(self, IRCOMM_TTY_SEARCH); | 992 | ircomm_tty_next_state(self, IRCOMM_TTY_SEARCH); |
978 | ircomm_tty_start_watchdog_timer(self, 3*HZ); | 993 | ircomm_tty_start_watchdog_timer(self, 3*HZ); |
979 | 994 | ||
980 | if (self->flags & ASYNC_CHECK_CD) { | 995 | if (self->port.flags & ASYNC_CHECK_CD) { |
981 | /* Drop carrier */ | 996 | /* Drop carrier */ |
982 | self->settings.dce = IRCOMM_DELTA_CD; | 997 | self->settings.dce = IRCOMM_DELTA_CD; |
983 | ircomm_tty_check_modem_status(self); | 998 | ircomm_tty_check_modem_status(self); |
984 | } else { | 999 | } else { |
1000 | struct tty_struct *tty = tty_port_tty_get(&self->port); | ||
985 | IRDA_DEBUG(0, "%s(), hanging up!\n", __func__ ); | 1001 | IRDA_DEBUG(0, "%s(), hanging up!\n", __func__ ); |
986 | if (self->tty) | 1002 | if (tty) { |
987 | tty_hangup(self->tty); | 1003 | tty_hangup(tty); |
1004 | tty_kref_put(tty); | ||
1005 | } | ||
988 | } | 1006 | } |
989 | break; | 1007 | break; |
990 | default: | 1008 | default: |
diff --git a/net/irda/ircomm/ircomm_tty_ioctl.c b/net/irda/ircomm/ircomm_tty_ioctl.c index d0667d68351d..b343f50dc8d7 100644 --- a/net/irda/ircomm/ircomm_tty_ioctl.c +++ b/net/irda/ircomm/ircomm_tty_ioctl.c | |||
@@ -52,17 +52,18 @@ | |||
52 | * Change speed of the driver. If the remote device is a DCE, then this | 52 | * Change speed of the driver. If the remote device is a DCE, then this |
53 | * should make it change the speed of its serial port | 53 | * should make it change the speed of its serial port |
54 | */ | 54 | */ |
55 | static void ircomm_tty_change_speed(struct ircomm_tty_cb *self) | 55 | static void ircomm_tty_change_speed(struct ircomm_tty_cb *self, |
56 | struct tty_struct *tty) | ||
56 | { | 57 | { |
57 | unsigned int cflag, cval; | 58 | unsigned int cflag, cval; |
58 | int baud; | 59 | int baud; |
59 | 60 | ||
60 | IRDA_DEBUG(2, "%s()\n", __func__ ); | 61 | IRDA_DEBUG(2, "%s()\n", __func__ ); |
61 | 62 | ||
62 | if (!self->tty || !self->tty->termios || !self->ircomm) | 63 | if (!self->ircomm) |
63 | return; | 64 | return; |
64 | 65 | ||
65 | cflag = self->tty->termios->c_cflag; | 66 | cflag = tty->termios.c_cflag; |
66 | 67 | ||
67 | /* byte size and parity */ | 68 | /* byte size and parity */ |
68 | switch (cflag & CSIZE) { | 69 | switch (cflag & CSIZE) { |
@@ -81,7 +82,7 @@ static void ircomm_tty_change_speed(struct ircomm_tty_cb *self) | |||
81 | cval |= IRCOMM_PARITY_EVEN; | 82 | cval |= IRCOMM_PARITY_EVEN; |
82 | 83 | ||
83 | /* Determine divisor based on baud rate */ | 84 | /* Determine divisor based on baud rate */ |
84 | baud = tty_get_baud_rate(self->tty); | 85 | baud = tty_get_baud_rate(tty); |
85 | if (!baud) | 86 | if (!baud) |
86 | baud = 9600; /* B0 transition handled in rs_set_termios */ | 87 | baud = 9600; /* B0 transition handled in rs_set_termios */ |
87 | 88 | ||
@@ -90,19 +91,19 @@ static void ircomm_tty_change_speed(struct ircomm_tty_cb *self) | |||
90 | 91 | ||
91 | /* CTS flow control flag and modem status interrupts */ | 92 | /* CTS flow control flag and modem status interrupts */ |
92 | if (cflag & CRTSCTS) { | 93 | if (cflag & CRTSCTS) { |
93 | self->flags |= ASYNC_CTS_FLOW; | 94 | self->port.flags |= ASYNC_CTS_FLOW; |
94 | self->settings.flow_control |= IRCOMM_RTS_CTS_IN; | 95 | self->settings.flow_control |= IRCOMM_RTS_CTS_IN; |
95 | /* This got me. Bummer. Jean II */ | 96 | /* This got me. Bummer. Jean II */ |
96 | if (self->service_type == IRCOMM_3_WIRE_RAW) | 97 | if (self->service_type == IRCOMM_3_WIRE_RAW) |
97 | IRDA_WARNING("%s(), enabling RTS/CTS on link that doesn't support it (3-wire-raw)\n", __func__); | 98 | IRDA_WARNING("%s(), enabling RTS/CTS on link that doesn't support it (3-wire-raw)\n", __func__); |
98 | } else { | 99 | } else { |
99 | self->flags &= ~ASYNC_CTS_FLOW; | 100 | self->port.flags &= ~ASYNC_CTS_FLOW; |
100 | self->settings.flow_control &= ~IRCOMM_RTS_CTS_IN; | 101 | self->settings.flow_control &= ~IRCOMM_RTS_CTS_IN; |
101 | } | 102 | } |
102 | if (cflag & CLOCAL) | 103 | if (cflag & CLOCAL) |
103 | self->flags &= ~ASYNC_CHECK_CD; | 104 | self->port.flags &= ~ASYNC_CHECK_CD; |
104 | else | 105 | else |
105 | self->flags |= ASYNC_CHECK_CD; | 106 | self->port.flags |= ASYNC_CHECK_CD; |
106 | #if 0 | 107 | #if 0 |
107 | /* | 108 | /* |
108 | * Set up parity check flag | 109 | * Set up parity check flag |
@@ -148,18 +149,18 @@ void ircomm_tty_set_termios(struct tty_struct *tty, | |||
148 | struct ktermios *old_termios) | 149 | struct ktermios *old_termios) |
149 | { | 150 | { |
150 | struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data; | 151 | struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data; |
151 | unsigned int cflag = tty->termios->c_cflag; | 152 | unsigned int cflag = tty->termios.c_cflag; |
152 | 153 | ||
153 | IRDA_DEBUG(2, "%s()\n", __func__ ); | 154 | IRDA_DEBUG(2, "%s()\n", __func__ ); |
154 | 155 | ||
155 | if ((cflag == old_termios->c_cflag) && | 156 | if ((cflag == old_termios->c_cflag) && |
156 | (RELEVANT_IFLAG(tty->termios->c_iflag) == | 157 | (RELEVANT_IFLAG(tty->termios.c_iflag) == |
157 | RELEVANT_IFLAG(old_termios->c_iflag))) | 158 | RELEVANT_IFLAG(old_termios->c_iflag))) |
158 | { | 159 | { |
159 | return; | 160 | return; |
160 | } | 161 | } |
161 | 162 | ||
162 | ircomm_tty_change_speed(self); | 163 | ircomm_tty_change_speed(self, tty); |
163 | 164 | ||
164 | /* Handle transition to B0 status */ | 165 | /* Handle transition to B0 status */ |
165 | if ((old_termios->c_cflag & CBAUD) && | 166 | if ((old_termios->c_cflag & CBAUD) && |
@@ -172,7 +173,7 @@ void ircomm_tty_set_termios(struct tty_struct *tty, | |||
172 | if (!(old_termios->c_cflag & CBAUD) && | 173 | if (!(old_termios->c_cflag & CBAUD) && |
173 | (cflag & CBAUD)) { | 174 | (cflag & CBAUD)) { |
174 | self->settings.dte |= IRCOMM_DTR; | 175 | self->settings.dte |= IRCOMM_DTR; |
175 | if (!(tty->termios->c_cflag & CRTSCTS) || | 176 | if (!(tty->termios.c_cflag & CRTSCTS) || |
176 | !test_bit(TTY_THROTTLED, &tty->flags)) { | 177 | !test_bit(TTY_THROTTLED, &tty->flags)) { |
177 | self->settings.dte |= IRCOMM_RTS; | 178 | self->settings.dte |= IRCOMM_RTS; |
178 | } | 179 | } |
@@ -181,7 +182,7 @@ void ircomm_tty_set_termios(struct tty_struct *tty, | |||
181 | 182 | ||
182 | /* Handle turning off CRTSCTS */ | 183 | /* Handle turning off CRTSCTS */ |
183 | if ((old_termios->c_cflag & CRTSCTS) && | 184 | if ((old_termios->c_cflag & CRTSCTS) && |
184 | !(tty->termios->c_cflag & CRTSCTS)) | 185 | !(tty->termios.c_cflag & CRTSCTS)) |
185 | { | 186 | { |
186 | tty->hw_stopped = 0; | 187 | tty->hw_stopped = 0; |
187 | ircomm_tty_start(tty); | 188 | ircomm_tty_start(tty); |
@@ -270,10 +271,10 @@ static int ircomm_tty_get_serial_info(struct ircomm_tty_cb *self, | |||
270 | 271 | ||
271 | memset(&info, 0, sizeof(info)); | 272 | memset(&info, 0, sizeof(info)); |
272 | info.line = self->line; | 273 | info.line = self->line; |
273 | info.flags = self->flags; | 274 | info.flags = self->port.flags; |
274 | info.baud_base = self->settings.data_rate; | 275 | info.baud_base = self->settings.data_rate; |
275 | info.close_delay = self->close_delay; | 276 | info.close_delay = self->port.close_delay; |
276 | info.closing_wait = self->closing_wait; | 277 | info.closing_wait = self->port.closing_wait; |
277 | 278 | ||
278 | /* For compatibility */ | 279 | /* For compatibility */ |
279 | info.type = PORT_16550A; | 280 | info.type = PORT_16550A; |