aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/n_gsm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/tty/n_gsm.c')
-rw-r--r--drivers/tty/n_gsm.c142
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
110struct gsm_msg { 110struct 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
680static void gsm_data_kick(struct gsm_mux *gsm) 681static 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)
971static void gsm_dlci_data_kick(struct gsm_dlci *dlci) 967static 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}
2051EXPORT_SYMBOL_GPL(gsm_cleanup_mux); 2058EXPORT_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 2879static int gsmtty_install(struct tty_driver *driver, struct tty_struct *tty)
2872static 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
2923static 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
3049static void gsmtty_throttle(struct tty_struct *tty) 3078static 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)
3059static void gsmtty_unthrottle(struct tty_struct *tty) 3088static 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 */
3087static const struct tty_operations gsmtty_ops = { 3116static 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,