diff options
Diffstat (limited to 'drivers/tty/n_gsm.c')
-rw-r--r-- | drivers/tty/n_gsm.c | 142 |
1 files changed, 86 insertions, 56 deletions
diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index c43b683b6eb8..3e210a430fb3 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c | |||
@@ -108,7 +108,7 @@ struct gsm_mux_net { | |||
108 | */ | 108 | */ |
109 | 109 | ||
110 | struct gsm_msg { | 110 | struct gsm_msg { |
111 | struct gsm_msg *next; | 111 | struct list_head list; |
112 | u8 addr; /* DLCI address + flags */ | 112 | u8 addr; /* DLCI address + flags */ |
113 | u8 ctrl; /* Control byte + flags */ | 113 | u8 ctrl; /* Control byte + flags */ |
114 | unsigned int len; /* Length of data block (can be zero) */ | 114 | unsigned int len; /* Length of data block (can be zero) */ |
@@ -245,8 +245,7 @@ struct gsm_mux { | |||
245 | unsigned int tx_bytes; /* TX data outstanding */ | 245 | unsigned int tx_bytes; /* TX data outstanding */ |
246 | #define TX_THRESH_HI 8192 | 246 | #define TX_THRESH_HI 8192 |
247 | #define TX_THRESH_LO 2048 | 247 | #define TX_THRESH_LO 2048 |
248 | struct gsm_msg *tx_head; /* Pending data packets */ | 248 | struct list_head tx_list; /* Pending data packets */ |
249 | struct gsm_msg *tx_tail; | ||
250 | 249 | ||
251 | /* Control messages */ | 250 | /* Control messages */ |
252 | struct timer_list t2_timer; /* Retransmit timer for commands */ | 251 | struct timer_list t2_timer; /* Retransmit timer for commands */ |
@@ -663,7 +662,7 @@ static struct gsm_msg *gsm_data_alloc(struct gsm_mux *gsm, u8 addr, int len, | |||
663 | m->len = len; | 662 | m->len = len; |
664 | m->addr = addr; | 663 | m->addr = addr; |
665 | m->ctrl = ctrl; | 664 | m->ctrl = ctrl; |
666 | m->next = NULL; | 665 | INIT_LIST_HEAD(&m->list); |
667 | return m; | 666 | return m; |
668 | } | 667 | } |
669 | 668 | ||
@@ -673,22 +672,21 @@ static struct gsm_msg *gsm_data_alloc(struct gsm_mux *gsm, u8 addr, int len, | |||
673 | * | 672 | * |
674 | * The tty device has called us to indicate that room has appeared in | 673 | * The tty device has called us to indicate that room has appeared in |
675 | * the transmit queue. Ram more data into the pipe if we have any | 674 | * the transmit queue. Ram more data into the pipe if we have any |
675 | * If we have been flow-stopped by a CMD_FCOFF, then we can only | ||
676 | * send messages on DLCI0 until CMD_FCON | ||
676 | * | 677 | * |
677 | * FIXME: lock against link layer control transmissions | 678 | * FIXME: lock against link layer control transmissions |
678 | */ | 679 | */ |
679 | 680 | ||
680 | static void gsm_data_kick(struct gsm_mux *gsm) | 681 | static void gsm_data_kick(struct gsm_mux *gsm) |
681 | { | 682 | { |
682 | struct gsm_msg *msg = gsm->tx_head; | 683 | struct gsm_msg *msg, *nmsg; |
683 | int len; | 684 | int len; |
684 | int skip_sof = 0; | 685 | int skip_sof = 0; |
685 | 686 | ||
686 | /* FIXME: We need to apply this solely to data messages */ | 687 | list_for_each_entry_safe(msg, nmsg, &gsm->tx_list, list) { |
687 | if (gsm->constipated) | 688 | if (gsm->constipated && msg->addr) |
688 | return; | 689 | continue; |
689 | |||
690 | while (gsm->tx_head != NULL) { | ||
691 | msg = gsm->tx_head; | ||
692 | if (gsm->encoding != 0) { | 690 | if (gsm->encoding != 0) { |
693 | gsm->txframe[0] = GSM1_SOF; | 691 | gsm->txframe[0] = GSM1_SOF; |
694 | len = gsm_stuff_frame(msg->data, | 692 | len = gsm_stuff_frame(msg->data, |
@@ -711,14 +709,13 @@ static void gsm_data_kick(struct gsm_mux *gsm) | |||
711 | len - skip_sof) < 0) | 709 | len - skip_sof) < 0) |
712 | break; | 710 | break; |
713 | /* FIXME: Can eliminate one SOF in many more cases */ | 711 | /* FIXME: Can eliminate one SOF in many more cases */ |
714 | gsm->tx_head = msg->next; | ||
715 | if (gsm->tx_head == NULL) | ||
716 | gsm->tx_tail = NULL; | ||
717 | gsm->tx_bytes -= msg->len; | 712 | gsm->tx_bytes -= msg->len; |
718 | kfree(msg); | ||
719 | /* For a burst of frames skip the extra SOF within the | 713 | /* For a burst of frames skip the extra SOF within the |
720 | burst */ | 714 | burst */ |
721 | skip_sof = 1; | 715 | skip_sof = 1; |
716 | |||
717 | list_del(&msg->list); | ||
718 | kfree(msg); | ||
722 | } | 719 | } |
723 | } | 720 | } |
724 | 721 | ||
@@ -768,11 +765,7 @@ static void __gsm_data_queue(struct gsm_dlci *dlci, struct gsm_msg *msg) | |||
768 | msg->data = dp; | 765 | msg->data = dp; |
769 | 766 | ||
770 | /* Add to the actual output queue */ | 767 | /* Add to the actual output queue */ |
771 | if (gsm->tx_tail) | 768 | list_add_tail(&msg->list, &gsm->tx_list); |
772 | gsm->tx_tail->next = msg; | ||
773 | else | ||
774 | gsm->tx_head = msg; | ||
775 | gsm->tx_tail = msg; | ||
776 | gsm->tx_bytes += msg->len; | 769 | gsm->tx_bytes += msg->len; |
777 | gsm_data_kick(gsm); | 770 | gsm_data_kick(gsm); |
778 | } | 771 | } |
@@ -875,7 +868,7 @@ static int gsm_dlci_data_output_framed(struct gsm_mux *gsm, | |||
875 | 868 | ||
876 | /* dlci->skb is locked by tx_lock */ | 869 | /* dlci->skb is locked by tx_lock */ |
877 | if (dlci->skb == NULL) { | 870 | if (dlci->skb == NULL) { |
878 | dlci->skb = skb_dequeue(&dlci->skb_list); | 871 | dlci->skb = skb_dequeue_tail(&dlci->skb_list); |
879 | if (dlci->skb == NULL) | 872 | if (dlci->skb == NULL) |
880 | return 0; | 873 | return 0; |
881 | first = 1; | 874 | first = 1; |
@@ -886,7 +879,7 @@ static int gsm_dlci_data_output_framed(struct gsm_mux *gsm, | |||
886 | if (len > gsm->mtu) { | 879 | if (len > gsm->mtu) { |
887 | if (dlci->adaption == 3) { | 880 | if (dlci->adaption == 3) { |
888 | /* Over long frame, bin it */ | 881 | /* Over long frame, bin it */ |
889 | kfree_skb(dlci->skb); | 882 | dev_kfree_skb_any(dlci->skb); |
890 | dlci->skb = NULL; | 883 | dlci->skb = NULL; |
891 | return 0; | 884 | return 0; |
892 | } | 885 | } |
@@ -899,8 +892,11 @@ static int gsm_dlci_data_output_framed(struct gsm_mux *gsm, | |||
899 | 892 | ||
900 | /* FIXME: need a timer or something to kick this so it can't | 893 | /* FIXME: need a timer or something to kick this so it can't |
901 | get stuck with no work outstanding and no buffer free */ | 894 | get stuck with no work outstanding and no buffer free */ |
902 | if (msg == NULL) | 895 | if (msg == NULL) { |
896 | skb_queue_tail(&dlci->skb_list, dlci->skb); | ||
897 | dlci->skb = NULL; | ||
903 | return -ENOMEM; | 898 | return -ENOMEM; |
899 | } | ||
904 | dp = msg->data; | 900 | dp = msg->data; |
905 | 901 | ||
906 | if (dlci->adaption == 4) { /* Interruptible framed (Packetised Data) */ | 902 | if (dlci->adaption == 4) { /* Interruptible framed (Packetised Data) */ |
@@ -912,7 +908,7 @@ static int gsm_dlci_data_output_framed(struct gsm_mux *gsm, | |||
912 | skb_pull(dlci->skb, len); | 908 | skb_pull(dlci->skb, len); |
913 | __gsm_data_queue(dlci, msg); | 909 | __gsm_data_queue(dlci, msg); |
914 | if (last) { | 910 | if (last) { |
915 | kfree_skb(dlci->skb); | 911 | dev_kfree_skb_any(dlci->skb); |
916 | dlci->skb = NULL; | 912 | dlci->skb = NULL; |
917 | } | 913 | } |
918 | return size; | 914 | return size; |
@@ -971,16 +967,22 @@ static void gsm_dlci_data_sweep(struct gsm_mux *gsm) | |||
971 | static void gsm_dlci_data_kick(struct gsm_dlci *dlci) | 967 | static void gsm_dlci_data_kick(struct gsm_dlci *dlci) |
972 | { | 968 | { |
973 | unsigned long flags; | 969 | unsigned long flags; |
970 | int sweep; | ||
971 | |||
972 | if (dlci->constipated) | ||
973 | return; | ||
974 | 974 | ||
975 | spin_lock_irqsave(&dlci->gsm->tx_lock, flags); | 975 | spin_lock_irqsave(&dlci->gsm->tx_lock, flags); |
976 | /* If we have nothing running then we need to fire up */ | 976 | /* If we have nothing running then we need to fire up */ |
977 | sweep = (dlci->gsm->tx_bytes < TX_THRESH_LO); | ||
977 | if (dlci->gsm->tx_bytes == 0) { | 978 | if (dlci->gsm->tx_bytes == 0) { |
978 | if (dlci->net) | 979 | if (dlci->net) |
979 | gsm_dlci_data_output_framed(dlci->gsm, dlci); | 980 | gsm_dlci_data_output_framed(dlci->gsm, dlci); |
980 | else | 981 | else |
981 | gsm_dlci_data_output(dlci->gsm, dlci); | 982 | gsm_dlci_data_output(dlci->gsm, dlci); |
982 | } else if (dlci->gsm->tx_bytes < TX_THRESH_LO) | 983 | } |
983 | gsm_dlci_data_sweep(dlci->gsm); | 984 | if (sweep) |
985 | gsm_dlci_data_sweep(dlci->gsm); | ||
984 | spin_unlock_irqrestore(&dlci->gsm->tx_lock, flags); | 986 | spin_unlock_irqrestore(&dlci->gsm->tx_lock, flags); |
985 | } | 987 | } |
986 | 988 | ||
@@ -1027,6 +1029,7 @@ static void gsm_process_modem(struct tty_struct *tty, struct gsm_dlci *dlci, | |||
1027 | { | 1029 | { |
1028 | int mlines = 0; | 1030 | int mlines = 0; |
1029 | u8 brk = 0; | 1031 | u8 brk = 0; |
1032 | int fc; | ||
1030 | 1033 | ||
1031 | /* The modem status command can either contain one octet (v.24 signals) | 1034 | /* The modem status command can either contain one octet (v.24 signals) |
1032 | or two octets (v.24 signals + break signals). The length field will | 1035 | or two octets (v.24 signals + break signals). The length field will |
@@ -1038,19 +1041,21 @@ static void gsm_process_modem(struct tty_struct *tty, struct gsm_dlci *dlci, | |||
1038 | else { | 1041 | else { |
1039 | brk = modem & 0x7f; | 1042 | brk = modem & 0x7f; |
1040 | modem = (modem >> 7) & 0x7f; | 1043 | modem = (modem >> 7) & 0x7f; |
1041 | }; | 1044 | } |
1042 | 1045 | ||
1043 | /* Flow control/ready to communicate */ | 1046 | /* Flow control/ready to communicate */ |
1044 | if (modem & MDM_FC) { | 1047 | fc = (modem & MDM_FC) || !(modem & MDM_RTR); |
1048 | if (fc && !dlci->constipated) { | ||
1045 | /* Need to throttle our output on this device */ | 1049 | /* Need to throttle our output on this device */ |
1046 | dlci->constipated = 1; | 1050 | dlci->constipated = 1; |
1047 | } | 1051 | } else if (!fc && dlci->constipated) { |
1048 | if (modem & MDM_RTC) { | ||
1049 | mlines |= TIOCM_DSR | TIOCM_DTR; | ||
1050 | dlci->constipated = 0; | 1052 | dlci->constipated = 0; |
1051 | gsm_dlci_data_kick(dlci); | 1053 | gsm_dlci_data_kick(dlci); |
1052 | } | 1054 | } |
1055 | |||
1053 | /* Map modem bits */ | 1056 | /* Map modem bits */ |
1057 | if (modem & MDM_RTC) | ||
1058 | mlines |= TIOCM_DSR | TIOCM_DTR; | ||
1054 | if (modem & MDM_RTR) | 1059 | if (modem & MDM_RTR) |
1055 | mlines |= TIOCM_RTS | TIOCM_CTS; | 1060 | mlines |= TIOCM_RTS | TIOCM_CTS; |
1056 | if (modem & MDM_IC) | 1061 | if (modem & MDM_IC) |
@@ -1061,7 +1066,7 @@ static void gsm_process_modem(struct tty_struct *tty, struct gsm_dlci *dlci, | |||
1061 | /* Carrier drop -> hangup */ | 1066 | /* Carrier drop -> hangup */ |
1062 | if (tty) { | 1067 | if (tty) { |
1063 | if ((mlines & TIOCM_CD) == 0 && (dlci->modem_rx & TIOCM_CD)) | 1068 | if ((mlines & TIOCM_CD) == 0 && (dlci->modem_rx & TIOCM_CD)) |
1064 | if (!(tty->termios->c_cflag & CLOCAL)) | 1069 | if (!(tty->termios.c_cflag & CLOCAL)) |
1065 | tty_hangup(tty); | 1070 | tty_hangup(tty); |
1066 | if (brk & 0x01) | 1071 | if (brk & 0x01) |
1067 | tty_insert_flip_char(tty, 0, TTY_BREAK); | 1072 | tty_insert_flip_char(tty, 0, TTY_BREAK); |
@@ -1190,6 +1195,8 @@ static void gsm_control_message(struct gsm_mux *gsm, unsigned int command, | |||
1190 | u8 *data, int clen) | 1195 | u8 *data, int clen) |
1191 | { | 1196 | { |
1192 | u8 buf[1]; | 1197 | u8 buf[1]; |
1198 | unsigned long flags; | ||
1199 | |||
1193 | switch (command) { | 1200 | switch (command) { |
1194 | case CMD_CLD: { | 1201 | case CMD_CLD: { |
1195 | struct gsm_dlci *dlci = gsm->dlci[0]; | 1202 | struct gsm_dlci *dlci = gsm->dlci[0]; |
@@ -1206,16 +1213,18 @@ static void gsm_control_message(struct gsm_mux *gsm, unsigned int command, | |||
1206 | gsm_control_reply(gsm, CMD_TEST, data, clen); | 1213 | gsm_control_reply(gsm, CMD_TEST, data, clen); |
1207 | break; | 1214 | break; |
1208 | case CMD_FCON: | 1215 | case CMD_FCON: |
1209 | /* Modem wants us to STFU */ | ||
1210 | gsm->constipated = 1; | ||
1211 | gsm_control_reply(gsm, CMD_FCON, NULL, 0); | ||
1212 | break; | ||
1213 | case CMD_FCOFF: | ||
1214 | /* Modem can accept data again */ | 1216 | /* Modem can accept data again */ |
1215 | gsm->constipated = 0; | 1217 | gsm->constipated = 0; |
1216 | gsm_control_reply(gsm, CMD_FCOFF, NULL, 0); | 1218 | gsm_control_reply(gsm, CMD_FCON, NULL, 0); |
1217 | /* Kick the link in case it is idling */ | 1219 | /* Kick the link in case it is idling */ |
1220 | spin_lock_irqsave(&gsm->tx_lock, flags); | ||
1218 | gsm_data_kick(gsm); | 1221 | gsm_data_kick(gsm); |
1222 | spin_unlock_irqrestore(&gsm->tx_lock, flags); | ||
1223 | break; | ||
1224 | case CMD_FCOFF: | ||
1225 | /* Modem wants us to STFU */ | ||
1226 | gsm->constipated = 1; | ||
1227 | gsm_control_reply(gsm, CMD_FCOFF, NULL, 0); | ||
1219 | break; | 1228 | break; |
1220 | case CMD_MSC: | 1229 | case CMD_MSC: |
1221 | /* Out of band modem line change indicator for a DLCI */ | 1230 | /* Out of band modem line change indicator for a DLCI */ |
@@ -1668,7 +1677,7 @@ static void gsm_dlci_free(struct kref *ref) | |||
1668 | dlci->gsm->dlci[dlci->addr] = NULL; | 1677 | dlci->gsm->dlci[dlci->addr] = NULL; |
1669 | kfifo_free(dlci->fifo); | 1678 | kfifo_free(dlci->fifo); |
1670 | while ((dlci->skb = skb_dequeue(&dlci->skb_list))) | 1679 | while ((dlci->skb = skb_dequeue(&dlci->skb_list))) |
1671 | kfree_skb(dlci->skb); | 1680 | dev_kfree_skb(dlci->skb); |
1672 | kfree(dlci); | 1681 | kfree(dlci); |
1673 | } | 1682 | } |
1674 | 1683 | ||
@@ -2007,7 +2016,7 @@ void gsm_cleanup_mux(struct gsm_mux *gsm) | |||
2007 | { | 2016 | { |
2008 | int i; | 2017 | int i; |
2009 | struct gsm_dlci *dlci = gsm->dlci[0]; | 2018 | struct gsm_dlci *dlci = gsm->dlci[0]; |
2010 | struct gsm_msg *txq; | 2019 | struct gsm_msg *txq, *ntxq; |
2011 | struct gsm_control *gc; | 2020 | struct gsm_control *gc; |
2012 | 2021 | ||
2013 | gsm->dead = 1; | 2022 | gsm->dead = 1; |
@@ -2042,11 +2051,9 @@ void gsm_cleanup_mux(struct gsm_mux *gsm) | |||
2042 | if (gsm->dlci[i]) | 2051 | if (gsm->dlci[i]) |
2043 | gsm_dlci_release(gsm->dlci[i]); | 2052 | gsm_dlci_release(gsm->dlci[i]); |
2044 | /* Now wipe the queues */ | 2053 | /* Now wipe the queues */ |
2045 | for (txq = gsm->tx_head; txq != NULL; txq = gsm->tx_head) { | 2054 | list_for_each_entry_safe(txq, ntxq, &gsm->tx_list, list) |
2046 | gsm->tx_head = txq->next; | ||
2047 | kfree(txq); | 2055 | kfree(txq); |
2048 | } | 2056 | INIT_LIST_HEAD(&gsm->tx_list); |
2049 | gsm->tx_tail = NULL; | ||
2050 | } | 2057 | } |
2051 | EXPORT_SYMBOL_GPL(gsm_cleanup_mux); | 2058 | EXPORT_SYMBOL_GPL(gsm_cleanup_mux); |
2052 | 2059 | ||
@@ -2157,6 +2164,7 @@ struct gsm_mux *gsm_alloc_mux(void) | |||
2157 | } | 2164 | } |
2158 | spin_lock_init(&gsm->lock); | 2165 | spin_lock_init(&gsm->lock); |
2159 | kref_init(&gsm->ref); | 2166 | kref_init(&gsm->ref); |
2167 | INIT_LIST_HEAD(&gsm->tx_list); | ||
2160 | 2168 | ||
2161 | gsm->t1 = T1; | 2169 | gsm->t1 = T1; |
2162 | gsm->t2 = T2; | 2170 | gsm->t2 = T2; |
@@ -2273,7 +2281,7 @@ static void gsmld_receive_buf(struct tty_struct *tty, const unsigned char *cp, | |||
2273 | gsm->error(gsm, *dp, flags); | 2281 | gsm->error(gsm, *dp, flags); |
2274 | break; | 2282 | break; |
2275 | default: | 2283 | default: |
2276 | WARN_ONCE("%s: unknown flag %d\n", | 2284 | WARN_ONCE(1, "%s: unknown flag %d\n", |
2277 | tty_name(tty, buf), flags); | 2285 | tty_name(tty, buf), flags); |
2278 | break; | 2286 | break; |
2279 | } | 2287 | } |
@@ -2377,12 +2385,12 @@ static void gsmld_write_wakeup(struct tty_struct *tty) | |||
2377 | 2385 | ||
2378 | /* Queue poll */ | 2386 | /* Queue poll */ |
2379 | clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); | 2387 | clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); |
2388 | spin_lock_irqsave(&gsm->tx_lock, flags); | ||
2380 | gsm_data_kick(gsm); | 2389 | gsm_data_kick(gsm); |
2381 | if (gsm->tx_bytes < TX_THRESH_LO) { | 2390 | if (gsm->tx_bytes < TX_THRESH_LO) { |
2382 | spin_lock_irqsave(&gsm->tx_lock, flags); | ||
2383 | gsm_dlci_data_sweep(gsm); | 2391 | gsm_dlci_data_sweep(gsm); |
2384 | spin_unlock_irqrestore(&gsm->tx_lock, flags); | ||
2385 | } | 2392 | } |
2393 | spin_unlock_irqrestore(&gsm->tx_lock, flags); | ||
2386 | } | 2394 | } |
2387 | 2395 | ||
2388 | /** | 2396 | /** |
@@ -2868,14 +2876,14 @@ static const struct tty_port_operations gsm_port_ops = { | |||
2868 | .dtr_rts = gsm_dtr_rts, | 2876 | .dtr_rts = gsm_dtr_rts, |
2869 | }; | 2877 | }; |
2870 | 2878 | ||
2871 | 2879 | static int gsmtty_install(struct tty_driver *driver, struct tty_struct *tty) | |
2872 | static int gsmtty_open(struct tty_struct *tty, struct file *filp) | ||
2873 | { | 2880 | { |
2874 | struct gsm_mux *gsm; | 2881 | struct gsm_mux *gsm; |
2875 | struct gsm_dlci *dlci; | 2882 | struct gsm_dlci *dlci; |
2876 | struct tty_port *port; | ||
2877 | unsigned int line = tty->index; | 2883 | unsigned int line = tty->index; |
2878 | unsigned int mux = line >> 6; | 2884 | unsigned int mux = line >> 6; |
2885 | bool alloc = false; | ||
2886 | int ret; | ||
2879 | 2887 | ||
2880 | line = line & 0x3F; | 2888 | line = line & 0x3F; |
2881 | 2889 | ||
@@ -2889,14 +2897,35 @@ static int gsmtty_open(struct tty_struct *tty, struct file *filp) | |||
2889 | gsm = gsm_mux[mux]; | 2897 | gsm = gsm_mux[mux]; |
2890 | if (gsm->dead) | 2898 | if (gsm->dead) |
2891 | return -EL2HLT; | 2899 | return -EL2HLT; |
2900 | /* If DLCI 0 is not yet fully open return an error. This is ok from a locking | ||
2901 | perspective as we don't have to worry about this if DLCI0 is lost */ | ||
2902 | if (gsm->dlci[0] && gsm->dlci[0]->state != DLCI_OPEN) | ||
2903 | return -EL2NSYNC; | ||
2892 | dlci = gsm->dlci[line]; | 2904 | dlci = gsm->dlci[line]; |
2893 | if (dlci == NULL) | 2905 | if (dlci == NULL) { |
2906 | alloc = true; | ||
2894 | dlci = gsm_dlci_alloc(gsm, line); | 2907 | dlci = gsm_dlci_alloc(gsm, line); |
2908 | } | ||
2895 | if (dlci == NULL) | 2909 | if (dlci == NULL) |
2896 | return -ENOMEM; | 2910 | return -ENOMEM; |
2897 | port = &dlci->port; | 2911 | ret = tty_port_install(&dlci->port, driver, tty); |
2898 | port->count++; | 2912 | if (ret) { |
2913 | if (alloc) | ||
2914 | dlci_put(dlci); | ||
2915 | return ret; | ||
2916 | } | ||
2917 | |||
2899 | tty->driver_data = dlci; | 2918 | tty->driver_data = dlci; |
2919 | |||
2920 | return 0; | ||
2921 | } | ||
2922 | |||
2923 | static int gsmtty_open(struct tty_struct *tty, struct file *filp) | ||
2924 | { | ||
2925 | struct gsm_dlci *dlci = tty->driver_data; | ||
2926 | struct tty_port *port = &dlci->port; | ||
2927 | |||
2928 | port->count++; | ||
2900 | dlci_get(dlci); | 2929 | dlci_get(dlci); |
2901 | dlci_get(dlci->gsm->dlci[0]); | 2930 | dlci_get(dlci->gsm->dlci[0]); |
2902 | mux_get(dlci->gsm); | 2931 | mux_get(dlci->gsm); |
@@ -3043,13 +3072,13 @@ static void gsmtty_set_termios(struct tty_struct *tty, struct ktermios *old) | |||
3043 | the RPN control message. This however rapidly gets nasty as we | 3072 | the RPN control message. This however rapidly gets nasty as we |
3044 | then have to remap modem signals each way according to whether | 3073 | then have to remap modem signals each way according to whether |
3045 | our virtual cable is null modem etc .. */ | 3074 | our virtual cable is null modem etc .. */ |
3046 | tty_termios_copy_hw(tty->termios, old); | 3075 | tty_termios_copy_hw(&tty->termios, old); |
3047 | } | 3076 | } |
3048 | 3077 | ||
3049 | static void gsmtty_throttle(struct tty_struct *tty) | 3078 | static void gsmtty_throttle(struct tty_struct *tty) |
3050 | { | 3079 | { |
3051 | struct gsm_dlci *dlci = tty->driver_data; | 3080 | struct gsm_dlci *dlci = tty->driver_data; |
3052 | if (tty->termios->c_cflag & CRTSCTS) | 3081 | if (tty->termios.c_cflag & CRTSCTS) |
3053 | dlci->modem_tx &= ~TIOCM_DTR; | 3082 | dlci->modem_tx &= ~TIOCM_DTR; |
3054 | dlci->throttled = 1; | 3083 | dlci->throttled = 1; |
3055 | /* Send an MSC with DTR cleared */ | 3084 | /* Send an MSC with DTR cleared */ |
@@ -3059,7 +3088,7 @@ static void gsmtty_throttle(struct tty_struct *tty) | |||
3059 | static void gsmtty_unthrottle(struct tty_struct *tty) | 3088 | static void gsmtty_unthrottle(struct tty_struct *tty) |
3060 | { | 3089 | { |
3061 | struct gsm_dlci *dlci = tty->driver_data; | 3090 | struct gsm_dlci *dlci = tty->driver_data; |
3062 | if (tty->termios->c_cflag & CRTSCTS) | 3091 | if (tty->termios.c_cflag & CRTSCTS) |
3063 | dlci->modem_tx |= TIOCM_DTR; | 3092 | dlci->modem_tx |= TIOCM_DTR; |
3064 | dlci->throttled = 0; | 3093 | dlci->throttled = 0; |
3065 | /* Send an MSC with DTR set */ | 3094 | /* Send an MSC with DTR set */ |
@@ -3085,6 +3114,7 @@ static int gsmtty_break_ctl(struct tty_struct *tty, int state) | |||
3085 | 3114 | ||
3086 | /* Virtual ttys for the demux */ | 3115 | /* Virtual ttys for the demux */ |
3087 | static const struct tty_operations gsmtty_ops = { | 3116 | static const struct tty_operations gsmtty_ops = { |
3117 | .install = gsmtty_install, | ||
3088 | .open = gsmtty_open, | 3118 | .open = gsmtty_open, |
3089 | .close = gsmtty_close, | 3119 | .close = gsmtty_close, |
3090 | .write = gsmtty_write, | 3120 | .write = gsmtty_write, |