diff options
-rw-r--r-- | include/net/irda/ircomm_tty.h | 1 | ||||
-rw-r--r-- | net/irda/ircomm/ircomm_param.c | 5 | ||||
-rw-r--r-- | net/irda/ircomm/ircomm_tty.c | 62 | ||||
-rw-r--r-- | net/irda/ircomm/ircomm_tty_attach.c | 33 | ||||
-rw-r--r-- | net/irda/ircomm/ircomm_tty_ioctl.c | 11 |
5 files changed, 70 insertions, 42 deletions
diff --git a/include/net/irda/ircomm_tty.h b/include/net/irda/ircomm_tty.h index a9027d8f670d..80ffde3bb164 100644 --- a/include/net/irda/ircomm_tty.h +++ b/include/net/irda/ircomm_tty.h | |||
@@ -62,7 +62,6 @@ struct ircomm_tty_cb { | |||
62 | 62 | ||
63 | int state; /* Connect state */ | 63 | int state; /* Connect state */ |
64 | 64 | ||
65 | struct tty_struct *tty; | ||
66 | struct ircomm_cb *ircomm; /* IrCOMM layer instance */ | 65 | struct ircomm_cb *ircomm; /* IrCOMM layer instance */ |
67 | 66 | ||
68 | struct sk_buff *tx_skb; /* Transmit buffer */ | 67 | struct sk_buff *tx_skb; /* Transmit buffer */ |
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 7b2152cfd42a..03acc073b8c3 100644 --- a/net/irda/ircomm/ircomm_tty.c +++ b/net/irda/ircomm/ircomm_tty.c | |||
@@ -242,18 +242,15 @@ err: | |||
242 | * | 242 | * |
243 | */ | 243 | */ |
244 | static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self, | 244 | static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self, |
245 | struct file *filp) | 245 | struct tty_struct *tty, struct file *filp) |
246 | { | 246 | { |
247 | DECLARE_WAITQUEUE(wait, current); | 247 | DECLARE_WAITQUEUE(wait, current); |
248 | int retval; | 248 | int retval; |
249 | int do_clocal = 0, extra_count = 0; | 249 | int do_clocal = 0, extra_count = 0; |
250 | unsigned long flags; | 250 | unsigned long flags; |
251 | struct tty_struct *tty; | ||
252 | 251 | ||
253 | IRDA_DEBUG(2, "%s()\n", __func__ ); | 252 | IRDA_DEBUG(2, "%s()\n", __func__ ); |
254 | 253 | ||
255 | tty = self->tty; | ||
256 | |||
257 | /* | 254 | /* |
258 | * If non-blocking mode is set, or the port is not enabled, | 255 | * If non-blocking mode is set, or the port is not enabled, |
259 | * then make the check up front and then exit. | 256 | * then make the check up front and then exit. |
@@ -412,8 +409,8 @@ static int ircomm_tty_open(struct tty_struct *tty, struct file *filp) | |||
412 | self->port.count++; | 409 | self->port.count++; |
413 | 410 | ||
414 | tty->driver_data = self; | 411 | tty->driver_data = self; |
415 | self->tty = tty; | ||
416 | spin_unlock_irqrestore(&self->port.lock, flags); | 412 | spin_unlock_irqrestore(&self->port.lock, flags); |
413 | tty_port_tty_set(&self->port, tty); | ||
417 | 414 | ||
418 | IRDA_DEBUG(1, "%s(), %s%d, count = %d\n", __func__ , tty->driver->name, | 415 | IRDA_DEBUG(1, "%s(), %s%d, count = %d\n", __func__ , tty->driver->name, |
419 | self->line, self->port.count); | 416 | self->line, self->port.count); |
@@ -467,7 +464,7 @@ static int ircomm_tty_open(struct tty_struct *tty, struct file *filp) | |||
467 | if (ret) | 464 | if (ret) |
468 | return ret; | 465 | return ret; |
469 | 466 | ||
470 | ret = ircomm_tty_block_til_ready(self, filp); | 467 | ret = ircomm_tty_block_til_ready(self, tty, filp); |
471 | if (ret) { | 468 | if (ret) { |
472 | IRDA_DEBUG(2, | 469 | IRDA_DEBUG(2, |
473 | "%s(), returning after block_til_ready with %d\n", __func__ , | 470 | "%s(), returning after block_til_ready with %d\n", __func__ , |
@@ -548,7 +545,6 @@ static void ircomm_tty_close(struct tty_struct *tty, struct file *filp) | |||
548 | 545 | ||
549 | spin_lock_irqsave(&self->port.lock, flags); | 546 | spin_lock_irqsave(&self->port.lock, flags); |
550 | tty->closing = 0; | 547 | tty->closing = 0; |
551 | self->tty = NULL; | ||
552 | 548 | ||
553 | if (self->port.blocked_open) { | 549 | if (self->port.blocked_open) { |
554 | if (self->port.close_delay) { | 550 | if (self->port.close_delay) { |
@@ -562,6 +558,7 @@ static void ircomm_tty_close(struct tty_struct *tty, struct file *filp) | |||
562 | self->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); | 558 | self->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); |
563 | spin_unlock_irqrestore(&self->port.lock, flags); | 559 | spin_unlock_irqrestore(&self->port.lock, flags); |
564 | wake_up_interruptible(&self->port.close_wait); | 560 | wake_up_interruptible(&self->port.close_wait); |
561 | tty_port_tty_set(&self->port, NULL); | ||
565 | } | 562 | } |
566 | 563 | ||
567 | /* | 564 | /* |
@@ -604,7 +601,7 @@ static void ircomm_tty_do_softint(struct work_struct *work) | |||
604 | if (!self || self->magic != IRCOMM_TTY_MAGIC) | 601 | if (!self || self->magic != IRCOMM_TTY_MAGIC) |
605 | return; | 602 | return; |
606 | 603 | ||
607 | tty = self->tty; | 604 | tty = tty_port_tty_get(&self->port); |
608 | if (!tty) | 605 | if (!tty) |
609 | return; | 606 | return; |
610 | 607 | ||
@@ -625,7 +622,7 @@ static void ircomm_tty_do_softint(struct work_struct *work) | |||
625 | } | 622 | } |
626 | 623 | ||
627 | if (tty->hw_stopped) | 624 | if (tty->hw_stopped) |
628 | return; | 625 | goto put; |
629 | 626 | ||
630 | /* Unlink transmit buffer */ | 627 | /* Unlink transmit buffer */ |
631 | spin_lock_irqsave(&self->spinlock, flags); | 628 | spin_lock_irqsave(&self->spinlock, flags); |
@@ -644,6 +641,8 @@ static void ircomm_tty_do_softint(struct work_struct *work) | |||
644 | 641 | ||
645 | /* Check if user (still) wants to be waken up */ | 642 | /* Check if user (still) wants to be waken up */ |
646 | tty_wakeup(tty); | 643 | tty_wakeup(tty); |
644 | put: | ||
645 | tty_kref_put(tty); | ||
647 | } | 646 | } |
648 | 647 | ||
649 | /* | 648 | /* |
@@ -1004,7 +1003,11 @@ static void ircomm_tty_hangup(struct tty_struct *tty) | |||
1004 | 1003 | ||
1005 | spin_lock_irqsave(&self->port.lock, flags); | 1004 | spin_lock_irqsave(&self->port.lock, flags); |
1006 | self->port.flags &= ~ASYNC_NORMAL_ACTIVE; | 1005 | self->port.flags &= ~ASYNC_NORMAL_ACTIVE; |
1007 | self->tty = NULL; | 1006 | if (self->port.tty) { |
1007 | set_bit(TTY_IO_ERROR, &self->port.tty->flags); | ||
1008 | tty_kref_put(self->port.tty); | ||
1009 | } | ||
1010 | self->port.tty = NULL; | ||
1008 | self->port.count = 0; | 1011 | self->port.count = 0; |
1009 | spin_unlock_irqrestore(&self->port.lock, flags); | 1012 | spin_unlock_irqrestore(&self->port.lock, flags); |
1010 | 1013 | ||
@@ -1068,7 +1071,7 @@ void ircomm_tty_check_modem_status(struct ircomm_tty_cb *self) | |||
1068 | IRDA_ASSERT(self != NULL, return;); | 1071 | IRDA_ASSERT(self != NULL, return;); |
1069 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); | 1072 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); |
1070 | 1073 | ||
1071 | tty = self->tty; | 1074 | tty = tty_port_tty_get(&self->port); |
1072 | 1075 | ||
1073 | status = self->settings.dce; | 1076 | status = self->settings.dce; |
1074 | 1077 | ||
@@ -1089,10 +1092,10 @@ void ircomm_tty_check_modem_status(struct ircomm_tty_cb *self) | |||
1089 | tty_hangup(tty); | 1092 | tty_hangup(tty); |
1090 | 1093 | ||
1091 | /* Hangup will remote the tty, so better break out */ | 1094 | /* Hangup will remote the tty, so better break out */ |
1092 | return; | 1095 | goto put; |
1093 | } | 1096 | } |
1094 | } | 1097 | } |
1095 | if (self->port.flags & ASYNC_CTS_FLOW) { | 1098 | if (tty && self->port.flags & ASYNC_CTS_FLOW) { |
1096 | if (tty->hw_stopped) { | 1099 | if (tty->hw_stopped) { |
1097 | if (status & IRCOMM_CTS) { | 1100 | if (status & IRCOMM_CTS) { |
1098 | IRDA_DEBUG(2, | 1101 | IRDA_DEBUG(2, |
@@ -1103,7 +1106,7 @@ void ircomm_tty_check_modem_status(struct ircomm_tty_cb *self) | |||
1103 | wake_up_interruptible(&self->port.open_wait); | 1106 | wake_up_interruptible(&self->port.open_wait); |
1104 | 1107 | ||
1105 | schedule_work(&self->tqueue); | 1108 | schedule_work(&self->tqueue); |
1106 | return; | 1109 | goto put; |
1107 | } | 1110 | } |
1108 | } else { | 1111 | } else { |
1109 | if (!(status & IRCOMM_CTS)) { | 1112 | if (!(status & IRCOMM_CTS)) { |
@@ -1113,6 +1116,8 @@ void ircomm_tty_check_modem_status(struct ircomm_tty_cb *self) | |||
1113 | } | 1116 | } |
1114 | } | 1117 | } |
1115 | } | 1118 | } |
1119 | put: | ||
1120 | tty_kref_put(tty); | ||
1116 | } | 1121 | } |
1117 | 1122 | ||
1118 | /* | 1123 | /* |
@@ -1125,6 +1130,7 @@ static int ircomm_tty_data_indication(void *instance, void *sap, | |||
1125 | struct sk_buff *skb) | 1130 | struct sk_buff *skb) |
1126 | { | 1131 | { |
1127 | struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance; | 1132 | struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance; |
1133 | struct tty_struct *tty; | ||
1128 | 1134 | ||
1129 | IRDA_DEBUG(2, "%s()\n", __func__ ); | 1135 | IRDA_DEBUG(2, "%s()\n", __func__ ); |
1130 | 1136 | ||
@@ -1132,7 +1138,8 @@ static int ircomm_tty_data_indication(void *instance, void *sap, | |||
1132 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;); | 1138 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;); |
1133 | IRDA_ASSERT(skb != NULL, return -1;); | 1139 | IRDA_ASSERT(skb != NULL, return -1;); |
1134 | 1140 | ||
1135 | if (!self->tty) { | 1141 | tty = tty_port_tty_get(&self->port); |
1142 | if (!tty) { | ||
1136 | IRDA_DEBUG(0, "%s(), no tty!\n", __func__ ); | 1143 | IRDA_DEBUG(0, "%s(), no tty!\n", __func__ ); |
1137 | return 0; | 1144 | return 0; |
1138 | } | 1145 | } |
@@ -1143,7 +1150,7 @@ static int ircomm_tty_data_indication(void *instance, void *sap, | |||
1143 | * Devices like WinCE can do this, and since they don't send any | 1150 | * Devices like WinCE can do this, and since they don't send any |
1144 | * params, we can just as well declare the hardware for running. | 1151 | * params, we can just as well declare the hardware for running. |
1145 | */ | 1152 | */ |
1146 | if (self->tty->hw_stopped && (self->flow == FLOW_START)) { | 1153 | if (tty->hw_stopped && (self->flow == FLOW_START)) { |
1147 | IRDA_DEBUG(0, "%s(), polling for line settings!\n", __func__ ); | 1154 | IRDA_DEBUG(0, "%s(), polling for line settings!\n", __func__ ); |
1148 | ircomm_param_request(self, IRCOMM_POLL, TRUE); | 1155 | ircomm_param_request(self, IRCOMM_POLL, TRUE); |
1149 | 1156 | ||
@@ -1156,8 +1163,9 @@ static int ircomm_tty_data_indication(void *instance, void *sap, | |||
1156 | * Use flip buffer functions since the code may be called from interrupt | 1163 | * Use flip buffer functions since the code may be called from interrupt |
1157 | * context | 1164 | * context |
1158 | */ | 1165 | */ |
1159 | tty_insert_flip_string(self->tty, skb->data, skb->len); | 1166 | tty_insert_flip_string(tty, skb->data, skb->len); |
1160 | tty_flip_buffer_push(self->tty); | 1167 | tty_flip_buffer_push(tty); |
1168 | tty_kref_put(tty); | ||
1161 | 1169 | ||
1162 | /* No need to kfree_skb - see ircomm_ttp_data_indication() */ | 1170 | /* No need to kfree_skb - see ircomm_ttp_data_indication() */ |
1163 | 1171 | ||
@@ -1208,12 +1216,13 @@ static void ircomm_tty_flow_indication(void *instance, void *sap, | |||
1208 | IRDA_ASSERT(self != NULL, return;); | 1216 | IRDA_ASSERT(self != NULL, return;); |
1209 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); | 1217 | IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); |
1210 | 1218 | ||
1211 | tty = self->tty; | 1219 | tty = tty_port_tty_get(&self->port); |
1212 | 1220 | ||
1213 | switch (cmd) { | 1221 | switch (cmd) { |
1214 | case FLOW_START: | 1222 | case FLOW_START: |
1215 | IRDA_DEBUG(2, "%s(), hw start!\n", __func__ ); | 1223 | IRDA_DEBUG(2, "%s(), hw start!\n", __func__ ); |
1216 | tty->hw_stopped = 0; | 1224 | if (tty) |
1225 | tty->hw_stopped = 0; | ||
1217 | 1226 | ||
1218 | /* ircomm_tty_do_softint will take care of the rest */ | 1227 | /* ircomm_tty_do_softint will take care of the rest */ |
1219 | schedule_work(&self->tqueue); | 1228 | schedule_work(&self->tqueue); |
@@ -1221,15 +1230,19 @@ static void ircomm_tty_flow_indication(void *instance, void *sap, | |||
1221 | default: /* If we get here, something is very wrong, better stop */ | 1230 | default: /* If we get here, something is very wrong, better stop */ |
1222 | case FLOW_STOP: | 1231 | case FLOW_STOP: |
1223 | IRDA_DEBUG(2, "%s(), hw stopped!\n", __func__ ); | 1232 | IRDA_DEBUG(2, "%s(), hw stopped!\n", __func__ ); |
1224 | tty->hw_stopped = 1; | 1233 | if (tty) |
1234 | tty->hw_stopped = 1; | ||
1225 | break; | 1235 | break; |
1226 | } | 1236 | } |
1237 | |||
1238 | tty_kref_put(tty); | ||
1227 | self->flow = cmd; | 1239 | self->flow = cmd; |
1228 | } | 1240 | } |
1229 | 1241 | ||
1230 | #ifdef CONFIG_PROC_FS | 1242 | #ifdef CONFIG_PROC_FS |
1231 | static void ircomm_tty_line_info(struct ircomm_tty_cb *self, struct seq_file *m) | 1243 | static void ircomm_tty_line_info(struct ircomm_tty_cb *self, struct seq_file *m) |
1232 | { | 1244 | { |
1245 | struct tty_struct *tty; | ||
1233 | char sep; | 1246 | char sep; |
1234 | 1247 | ||
1235 | seq_printf(m, "State: %s\n", ircomm_tty_state[self->state]); | 1248 | seq_printf(m, "State: %s\n", ircomm_tty_state[self->state]); |
@@ -1356,9 +1369,12 @@ static void ircomm_tty_line_info(struct ircomm_tty_cb *self, struct seq_file *m) | |||
1356 | seq_printf(m, "Max data size: %d\n", self->max_data_size); | 1369 | seq_printf(m, "Max data size: %d\n", self->max_data_size); |
1357 | seq_printf(m, "Max header size: %d\n", self->max_header_size); | 1370 | seq_printf(m, "Max header size: %d\n", self->max_header_size); |
1358 | 1371 | ||
1359 | if (self->tty) | 1372 | tty = tty_port_tty_get(&self->port); |
1373 | if (tty) { | ||
1360 | seq_printf(m, "Hardware: %s\n", | 1374 | seq_printf(m, "Hardware: %s\n", |
1361 | self->tty->hw_stopped ? "Stopped" : "Running"); | 1375 | tty->hw_stopped ? "Stopped" : "Running"); |
1376 | tty_kref_put(tty); | ||
1377 | } | ||
1362 | } | 1378 | } |
1363 | 1379 | ||
1364 | static int ircomm_tty_proc_show(struct seq_file *m, void *v) | 1380 | 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 bed311af7311..3ab70e7a0715 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); |
@@ -569,17 +581,19 @@ void ircomm_tty_link_established(struct ircomm_tty_cb *self) | |||
569 | if ((self->port.flags & ASYNC_CTS_FLOW) && | 581 | if ((self->port.flags & ASYNC_CTS_FLOW) && |
570 | ((self->settings.dce & IRCOMM_CTS) == 0)) { | 582 | ((self->settings.dce & IRCOMM_CTS) == 0)) { |
571 | IRDA_DEBUG(0, "%s(), waiting for CTS ...\n", __func__ ); | 583 | IRDA_DEBUG(0, "%s(), waiting for CTS ...\n", __func__ ); |
572 | return; | 584 | goto put; |
573 | } else { | 585 | } else { |
574 | IRDA_DEBUG(1, "%s(), starting hardware!\n", __func__ ); | 586 | IRDA_DEBUG(1, "%s(), starting hardware!\n", __func__ ); |
575 | 587 | ||
576 | self->tty->hw_stopped = 0; | 588 | tty->hw_stopped = 0; |
577 | 589 | ||
578 | /* Wake up processes blocked on open */ | 590 | /* Wake up processes blocked on open */ |
579 | wake_up_interruptible(&self->port.open_wait); | 591 | wake_up_interruptible(&self->port.open_wait); |
580 | } | 592 | } |
581 | 593 | ||
582 | schedule_work(&self->tqueue); | 594 | schedule_work(&self->tqueue); |
595 | put: | ||
596 | tty_kref_put(tty); | ||
583 | } | 597 | } |
584 | 598 | ||
585 | /* | 599 | /* |
@@ -983,9 +997,12 @@ static int ircomm_tty_state_ready(struct ircomm_tty_cb *self, | |||
983 | self->settings.dce = IRCOMM_DELTA_CD; | 997 | self->settings.dce = IRCOMM_DELTA_CD; |
984 | ircomm_tty_check_modem_status(self); | 998 | ircomm_tty_check_modem_status(self); |
985 | } else { | 999 | } else { |
1000 | struct tty_struct *tty = tty_port_tty_get(&self->port); | ||
986 | IRDA_DEBUG(0, "%s(), hanging up!\n", __func__ ); | 1001 | IRDA_DEBUG(0, "%s(), hanging up!\n", __func__ ); |
987 | if (self->tty) | 1002 | if (tty) { |
988 | tty_hangup(self->tty); | 1003 | tty_hangup(tty); |
1004 | tty_kref_put(tty); | ||
1005 | } | ||
989 | } | 1006 | } |
990 | break; | 1007 | break; |
991 | default: | 1008 | default: |
diff --git a/net/irda/ircomm/ircomm_tty_ioctl.c b/net/irda/ircomm/ircomm_tty_ioctl.c index 31b917e9c8d8..0eab6500e99f 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 | ||
@@ -159,7 +160,7 @@ void ircomm_tty_set_termios(struct tty_struct *tty, | |||
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) && |