@@ -439,7 +439,7 @@ static u8 gsm_encode_modem(const struct gsm_dlci *dlci)
439439 modembits |= MDM_RTR ;
440440 if (dlci -> modem_tx & TIOCM_RI )
441441 modembits |= MDM_IC ;
442- if (dlci -> modem_tx & TIOCM_CD )
442+ if (dlci -> modem_tx & TIOCM_CD || dlci -> gsm -> initiator )
443443 modembits |= MDM_DV ;
444444 return modembits ;
445445}
@@ -448,7 +448,7 @@ static u8 gsm_encode_modem(const struct gsm_dlci *dlci)
448448 * gsm_print_packet - display a frame for debug
449449 * @hdr: header to print before decode
450450 * @addr: address EA from the frame
451- * @cr: C/R bit from the frame
451+ * @cr: C/R bit seen as initiator
452452 * @control: control including PF bit
453453 * @data: following data bytes
454454 * @dlen: length of data
@@ -548,7 +548,7 @@ static int gsm_stuff_frame(const u8 *input, u8 *output, int len)
548548 * gsm_send - send a control frame
549549 * @gsm: our GSM mux
550550 * @addr: address for control frame
551- * @cr: command/response bit
551+ * @cr: command/response bit seen as initiator
552552 * @control: control byte including PF bit
553553 *
554554 * Format up and transmit a control frame. These do not go via the
@@ -563,11 +563,15 @@ static void gsm_send(struct gsm_mux *gsm, int addr, int cr, int control)
563563 int len ;
564564 u8 cbuf [10 ];
565565 u8 ibuf [3 ];
566+ int ocr ;
567+
568+ /* toggle C/R coding if not initiator */
569+ ocr = cr ^ (gsm -> initiator ? 0 : 1 );
566570
567571 switch (gsm -> encoding ) {
568572 case 0 :
569573 cbuf [0 ] = GSM0_SOF ;
570- cbuf [1 ] = (addr << 2 ) | (cr << 1 ) | EA ;
574+ cbuf [1 ] = (addr << 2 ) | (ocr << 1 ) | EA ;
571575 cbuf [2 ] = control ;
572576 cbuf [3 ] = EA ; /* Length of data = 0 */
573577 cbuf [4 ] = 0xFF - gsm_fcs_add_block (INIT_FCS , cbuf + 1 , 3 );
@@ -577,7 +581,7 @@ static void gsm_send(struct gsm_mux *gsm, int addr, int cr, int control)
577581 case 1 :
578582 case 2 :
579583 /* Control frame + packing (but not frame stuffing) in mode 1 */
580- ibuf [0 ] = (addr << 2 ) | (cr << 1 ) | EA ;
584+ ibuf [0 ] = (addr << 2 ) | (ocr << 1 ) | EA ;
581585 ibuf [1 ] = control ;
582586 ibuf [2 ] = 0xFF - gsm_fcs_add_block (INIT_FCS , ibuf , 2 );
583587 /* Stuffing may double the size worst case */
@@ -611,7 +615,7 @@ static void gsm_send(struct gsm_mux *gsm, int addr, int cr, int control)
611615
612616static inline void gsm_response (struct gsm_mux * gsm , int addr , int control )
613617{
614- gsm_send (gsm , addr , 1 , control );
618+ gsm_send (gsm , addr , 0 , control );
615619}
616620
617621/**
@@ -1017,25 +1021,25 @@ static void gsm_control_reply(struct gsm_mux *gsm, int cmd, const u8 *data,
10171021 * @tty: virtual tty bound to the DLCI
10181022 * @dlci: DLCI to affect
10191023 * @modem: modem bits (full EA)
1020- * @clen: command length
1024+ * @slen: number of signal octets
10211025 *
10221026 * Used when a modem control message or line state inline in adaption
10231027 * layer 2 is processed. Sort out the local modem state and throttles
10241028 */
10251029
10261030static void gsm_process_modem (struct tty_struct * tty , struct gsm_dlci * dlci ,
1027- u32 modem , int clen )
1031+ u32 modem , int slen )
10281032{
10291033 int mlines = 0 ;
10301034 u8 brk = 0 ;
10311035 int fc ;
10321036
1033- /* The modem status command can either contain one octet (v .24 signals)
1034- or two octets (v .24 signals + break signals). The length field will
1035- either be 2 or 3 respectively. This is specified in section
1036- 5.4.6.3.7 of the 27.010 mux spec. */
1037+ /* The modem status command can either contain one octet (V .24 signals)
1038+ * or two octets (V .24 signals + break signals). This is specified in
1039+ * section 5.4.6.3.7 of the 07.10 mux spec.
1040+ */
10371041
1038- if (clen == 2 )
1042+ if (slen == 1 )
10391043 modem = modem & 0x7f ;
10401044 else {
10411045 brk = modem & 0x7f ;
@@ -1092,6 +1096,7 @@ static void gsm_control_modem(struct gsm_mux *gsm, const u8 *data, int clen)
10921096 unsigned int brk = 0 ;
10931097 struct gsm_dlci * dlci ;
10941098 int len = clen ;
1099+ int slen ;
10951100 const u8 * dp = data ;
10961101 struct tty_struct * tty ;
10971102
@@ -1111,6 +1116,7 @@ static void gsm_control_modem(struct gsm_mux *gsm, const u8 *data, int clen)
11111116 return ;
11121117 dlci = gsm -> dlci [addr ];
11131118
1119+ slen = len ;
11141120 while (gsm_read_ea (& modem , * dp ++ ) == 0 ) {
11151121 len -- ;
11161122 if (len == 0 )
@@ -1127,7 +1133,7 @@ static void gsm_control_modem(struct gsm_mux *gsm, const u8 *data, int clen)
11271133 modem |= (brk & 0x7f );
11281134 }
11291135 tty = tty_port_tty_get (& dlci -> port );
1130- gsm_process_modem (tty , dlci , modem , clen );
1136+ gsm_process_modem (tty , dlci , modem , slen );
11311137 if (tty ) {
11321138 tty_wakeup (tty );
11331139 tty_kref_put (tty );
@@ -1451,6 +1457,9 @@ static void gsm_dlci_close(struct gsm_dlci *dlci)
14511457 if (dlci -> addr != 0 ) {
14521458 tty_port_tty_hangup (& dlci -> port , false);
14531459 kfifo_reset (& dlci -> fifo );
1460+ /* Ensure that gsmtty_open() can return. */
1461+ tty_port_set_initialized (& dlci -> port , 0 );
1462+ wake_up_interruptible (& dlci -> port .open_wait );
14541463 } else
14551464 dlci -> gsm -> dead = true;
14561465 /* Unregister gsmtty driver,report gsmtty dev remove uevent for user */
@@ -1514,7 +1523,7 @@ static void gsm_dlci_t1(struct timer_list *t)
15141523 dlci -> mode = DLCI_MODE_ADM ;
15151524 gsm_dlci_open (dlci );
15161525 } else {
1517- gsm_dlci_close (dlci );
1526+ gsm_dlci_begin_close (dlci ); /* prevent half open link */
15181527 }
15191528
15201529 break ;
@@ -1593,6 +1602,7 @@ static void gsm_dlci_data(struct gsm_dlci *dlci, const u8 *data, int clen)
15931602 struct tty_struct * tty ;
15941603 unsigned int modem = 0 ;
15951604 int len = clen ;
1605+ int slen = 0 ;
15961606
15971607 if (debug & 16 )
15981608 pr_debug ("%d bytes for tty\n" , len );
@@ -1605,12 +1615,14 @@ static void gsm_dlci_data(struct gsm_dlci *dlci, const u8 *data, int clen)
16051615 case 2 : /* Asynchronous serial with line state in each frame */
16061616 while (gsm_read_ea (& modem , * data ++ ) == 0 ) {
16071617 len -- ;
1618+ slen ++ ;
16081619 if (len == 0 )
16091620 return ;
16101621 }
1622+ slen ++ ;
16111623 tty = tty_port_tty_get (port );
16121624 if (tty ) {
1613- gsm_process_modem (tty , dlci , modem , clen );
1625+ gsm_process_modem (tty , dlci , modem , slen );
16141626 tty_kref_put (tty );
16151627 }
16161628 fallthrough ;
@@ -1748,7 +1760,12 @@ static void gsm_dlci_release(struct gsm_dlci *dlci)
17481760 gsm_destroy_network (dlci );
17491761 mutex_unlock (& dlci -> mutex );
17501762
1751- tty_hangup (tty );
1763+ /* We cannot use tty_hangup() because in tty_kref_put() the tty
1764+ * driver assumes that the hangup queue is free and reuses it to
1765+ * queue release_one_tty() -> NULL pointer panic in
1766+ * process_one_work().
1767+ */
1768+ tty_vhangup (tty );
17521769
17531770 tty_port_tty_set (& dlci -> port , NULL );
17541771 tty_kref_put (tty );
@@ -1800,10 +1817,10 @@ static void gsm_queue(struct gsm_mux *gsm)
18001817 goto invalid ;
18011818
18021819 cr = gsm -> address & 1 ; /* C/R bit */
1820+ cr ^= gsm -> initiator ? 0 : 1 ; /* Flip so 1 always means command */
18031821
18041822 gsm_print_packet ("<--" , address , cr , gsm -> control , gsm -> buf , gsm -> len );
18051823
1806- cr ^= 1 - gsm -> initiator ; /* Flip so 1 always means command */
18071824 dlci = gsm -> dlci [address ];
18081825
18091826 switch (gsm -> control ) {
@@ -3234,9 +3251,9 @@ static void gsmtty_throttle(struct tty_struct *tty)
32343251 if (dlci -> state == DLCI_CLOSED )
32353252 return ;
32363253 if (C_CRTSCTS (tty ))
3237- dlci -> modem_tx &= ~TIOCM_DTR ;
3254+ dlci -> modem_tx &= ~TIOCM_RTS ;
32383255 dlci -> throttled = true;
3239- /* Send an MSC with DTR cleared */
3256+ /* Send an MSC with RTS cleared */
32403257 gsmtty_modem_update (dlci , 0 );
32413258}
32423259
@@ -3246,9 +3263,9 @@ static void gsmtty_unthrottle(struct tty_struct *tty)
32463263 if (dlci -> state == DLCI_CLOSED )
32473264 return ;
32483265 if (C_CRTSCTS (tty ))
3249- dlci -> modem_tx |= TIOCM_DTR ;
3266+ dlci -> modem_tx |= TIOCM_RTS ;
32503267 dlci -> throttled = false;
3251- /* Send an MSC with DTR set */
3268+ /* Send an MSC with RTS set */
32523269 gsmtty_modem_update (dlci , 0 );
32533270}
32543271
0 commit comments