diff options
author | Olof Johansson <olof@lixom.net> | 2012-09-29 16:07:34 -0400 |
---|---|---|
committer | Olof Johansson <olof@lixom.net> | 2012-09-29 16:07:34 -0400 |
commit | ad932bb6b549722a561fb31ac2fa50dcbcb3e36b (patch) | |
tree | 66cde27bd288e011a6e4cff87d342666399a1266 /net | |
parent | 5698bd757d55b1bb87edd1a9744ab09c142abfc2 (diff) | |
parent | 9cd68fa707cf6372f33eb51a5719dd7626efe5f6 (diff) |
Merge tag 'omap-devel-late-for-v3.7' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap into late/soc
These changes take us a step closer to merging the common clock
framework for omap but unfortunately these patches were not
ready for merging earlier. See also the notes below on the
dependencies these patches have, they are based on a merge
of sereral branches already merged.
From Paul Walmsley <paul@pwsan.com>:
OMAP patches intended for the 3.7 merge window:
- Runtime PM conversions for the GPMC and RNG IP blocks
- Preparation patches for the OMAP common clock framework conversion
- clkdev alias additions required by other drivers
- Performance Monitoring Unit (PMU) support for OMAP2, 3, and non-4430 OMAP4
- OMAP hwmod code and data improvements
- Preparation patches for the IOMMU runtime PM conversion
- Preparation patches for OMAP4 full-chip retention support
Based on a merge of v3.6-rc6, the omap-cleanup-b-for-3.7 tag
(7852ec0536ca39cefffc6301dc77f8ae55592926),the cleanup-fixes-for-v3.7
tag (de6ca33a96a6bf61fcb91d3d399703e19ead9d1e), and the
omap-devel-am33xx-for-v3.7 tag
(11964f53eb4d9ce59a058be9999d9cfcb1ced878), due to dependencies.
* tag 'omap-devel-late-for-v3.7' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap: (281 commits)
ARM: OMAP4460/4470: PMU: Enable PMU for OMAP4460/70
ARM: OMAP2+: PMU: Add runtime PM support
ARM: OMAP4430: PMU: prepare to create PMU device via HWMOD
ARM: OMAP2+: PMU: Convert OMAP2/3 devices to use HWMOD
ARM: OMAP3: hwmod data: Add debugss HWMOD data
ARM: OMAP2+: clockdomain/hwmod: add workaround for EMU clockdomain idle problems
ARM: OMAP: Add a timer attribute for timers that can interrupt the DSP
hwrng: OMAP: remove SoC restrictions from driver registration
ARM: OMAP: split OMAP1, OMAP2+ RNG device registration
hwrng: OMAP: convert to use runtime PM
hwrng: OMAP: store per-device data in per-device variables, not file statics
ARM: OMAP2xxx: hwmod/CM: add RNG integration data
ARM: OMAP2+: gpmc: minimal driver support
ARM: OMAP2+: gpmc: Adapt to HWMOD
ARM: OMAP2/3: hwmod data: add gpmc
ARM: OMAP4: hwmod data: add mmu hwmod for ipu and dsp
ARM: OMAP3: hwmod data: add mmu data for iva and isp
ARM: OMAP: iommu: fix including iommu.h without IOMMU_API selected
ARM: OMAP4: hwmod data: add missing HWMOD_NO_IDLEST flags to some PRCM IP blocks
ARM: OMAP4: hwmod data: make *phy_48m* as the main_clk of ocp2scp
...
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; |