LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
* [PATCH 1/8] tty: n_gsm: Add some instructions and code for requester
@ 2021-08-20 12:17 Zhenguo Zhao
  2021-08-20 12:17 ` [PATCH 2/8] tty: n_gsm: Modify cr bit value when config requester Zhenguo Zhao
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: Zhenguo Zhao @ 2021-08-20 12:17 UTC (permalink / raw)
  To: nianfu.bai, gregkh, jirislaby; +Cc: linux-kernel

From: Zhenguo Zhao <Zhenguo.Zhao1@unisoc.com>

The gsm driver can configure initiator or requester by parameter
initiator,but the config code and using are different ,the doc has
initiator instructions only,it should be add instructions for requester.

Signed-off-by: Zhenguo Zhao <Zhenguo.Zhao1@unisoc.com>
---
 Documentation/driver-api/serial/n_gsm.rst | 71 +++++++++++++++++++++++++++----
 1 file changed, 62 insertions(+), 9 deletions(-)

diff --git a/Documentation/driver-api/serial/n_gsm.rst b/Documentation/driver-api/serial/n_gsm.rst
index 87dfcd5..8fe723a 100644
--- a/Documentation/driver-api/serial/n_gsm.rst
+++ b/Documentation/driver-api/serial/n_gsm.rst
@@ -12,13 +12,16 @@ modems connected to a physical serial port.
 
 How to use it
 -------------
-1. initialize the modem in 0710 mux mode (usually AT+CMUX= command) through
-   its serial port. Depending on the modem used, you can pass more or less
-   parameters to this command,
-2. switch the serial line to using the n_gsm line discipline by using
-   TIOCSETD ioctl,
-3. configure the mux using GSMIOC_GETCONF / GSMIOC_SETCONF ioctl,
-4. obtain base gsmtty number for the used serial port,
+1. config initiator
+^^^^^^^^^^^^^^^^^^^^^
+
+1.1 initialize the modem in 0710 mux mode (usually AT+CMUX= command) through
+    its serial port. Depending on the modem used, you can pass more or less
+    parameters to this command.
+1.2 switch the serial line to using the n_gsm line discipline by using
+    TIOCSETD ioctl.
+1.3 configure the mux using GSMIOC_GETCONF / GSMIOC_SETCONF ioctl.
+1.4 obtain base gsmtty number for the used serial port.
 
 Major parts of the initialization program :
 (a good starting point is util-linux-ng/sys-utils/ldattach.c)::
@@ -70,14 +73,14 @@ Major parts of the initialization program :
 	daemon(0,0);
 	pause();
 
-5. use these devices as plain serial ports.
+1.5 use these devices as plain serial ports.
 
    for example, it's possible:
 
    - and to use gnokii to send / receive SMS on ttygsm1
    - to use ppp to establish a datalink on ttygsm2
 
-6. first close all virtual ports before closing the physical port.
+1.6 first close all virtual ports before closing the physical port.
 
    Note that after closing the physical port the modem is still in multiplexing
    mode. This may prevent a successful re-opening of the port later. To avoid
@@ -87,6 +90,56 @@ Major parts of the initialization program :
 
       0xf9, 0x03, 0xef, 0x03, 0xc3, 0x16, 0xf9.
 
+2. config requester
+^^^^^^^^^^^^^^^^^^^^^
+
+2.1 receive string "AT+CMUX= command" through its serial port,initialize
+    mux mode config
+2.2 switch the serial line to using the n_gsm line discipline by using
+    TIOCSETD ioctl.
+2.3 configure the mux using GSMIOC_GETCONF / GSMIOC_SETCONF ioctl.
+2.4 obtain base gsmtty number for the used serial port,
+
+  #include <stdio.h>
+  #include <stdint.h>
+  #include <linux/gsmmux.h>
+  #include <linux/tty.h>
+  #define DEFAULT_SPEED	B115200
+  #define SERIAL_PORT	/dev/ttyS0
+
+	int ldisc = N_GSM0710;
+	struct gsm_config c;
+	struct termios configuration;
+	uint32_t first;
+
+	/* open the serial port */
+	fd = open(SERIAL_PORT, O_RDWR | O_NOCTTY | O_NDELAY);
+
+	/* configure the serial port : speed, flow control ... */
+
+	/* get serial data and check "AT+CMUX=command" parameter ... */
+
+	/* use n_gsm line discipline */
+	ioctl(fd, TIOCSETD, &ldisc);
+
+	/* get n_gsm configuration */
+	ioctl(fd, GSMIOC_GETCONF, &c);
+	/* we are requester and need encoding 0 (basic) */
+	c.initiator = 0;
+	c.encapsulation = 0;
+	/* our modem defaults to a maximum size of 127 bytes */
+	c.mru = 127;
+	c.mtu = 127;
+	/* set the new configuration */
+	ioctl(fd, GSMIOC_SETCONF, &c);
+	/* get first gsmtty device node */
+	ioctl(fd, GSMIOC_GETFIRST, &first);
+	printf("first muxed line: /dev/gsmtty%i\n", first);
+
+	/* and wait for ever to keep the line discipline enabled */
+	daemon(0,0);
+	pause();
+
 Additional Documentation
 ------------------------
 More practical details on the protocol and how it's supported by industrial
-- 
1.9.1


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 2/8] tty: n_gsm: Modify cr bit value when config requester
  2021-08-20 12:17 [PATCH 1/8] tty: n_gsm: Add some instructions and code for requester Zhenguo Zhao
@ 2021-08-20 12:17 ` Zhenguo Zhao
  2021-08-20 12:17 ` [PATCH 3/8] tty: n_gsm: Modify CR,PF bit " Zhenguo Zhao
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Zhenguo Zhao @ 2021-08-20 12:17 UTC (permalink / raw)
  To: nianfu.bai, gregkh, jirislaby; +Cc: linux-kernel

From: Zhenguo Zhao <Zhenguo.Zhao1@unisoc.com>

When n_gsm config "initiator=0",as requester,gsmld will receive dlci
SABM and DISC control command frame,the CR bit value should be 1.

If cr == 0,it will goto invalid,and it can't send UA response
frame and open requster dlci.

        case SABM|PF:
-               if (cr == 0)
+               if (cr == 0) {
+                       printk("gsm_queue invalid\n");
                        goto invalid;
+                       }

Example,gsmld receive dlc0 SABM command frame:f9 03 3f 01 1c f9
but gsmld goto invalid.

Kernel test log:
[  101.794705] c0 gsmld_receive: 00000000: f9 03 3f 01 1c f9
[  101.803341] c0 <-- 0) C: SABM(P)
[  101.811371] c0 gsm_queue invalid

Signed-off-by: Zhenguo Zhao <Zhenguo.Zhao1@unisoc.com>
---
 drivers/tty/n_gsm.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
index 5fea02c..becca2c 100644
--- a/drivers/tty/n_gsm.c
+++ b/drivers/tty/n_gsm.c
@@ -1779,7 +1779,7 @@ static void gsm_queue(struct gsm_mux *gsm)
 
 	switch (gsm->control) {
 	case SABM|PF:
-		if (cr == 0)
+		if (cr == 1)
 			goto invalid;
 		if (dlci == NULL)
 			dlci = gsm_dlci_alloc(gsm, address);
@@ -1793,7 +1793,7 @@ static void gsm_queue(struct gsm_mux *gsm)
 		}
 		break;
 	case DISC|PF:
-		if (cr == 0)
+		if (cr == 1)
 			goto invalid;
 		if (dlci == NULL || dlci->state == DLCI_CLOSED) {
 			gsm_response(gsm, address, DM);
-- 
1.9.1


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 3/8] tty: n_gsm: Modify CR,PF bit when config requester
  2021-08-20 12:17 [PATCH 1/8] tty: n_gsm: Add some instructions and code for requester Zhenguo Zhao
  2021-08-20 12:17 ` [PATCH 2/8] tty: n_gsm: Modify cr bit value when config requester Zhenguo Zhao
@ 2021-08-20 12:17 ` Zhenguo Zhao
  2021-08-20 12:17 ` [PATCH 4/8] tty: n_gsm: Modify CR,PF bit printk info " Zhenguo Zhao
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Zhenguo Zhao @ 2021-08-20 12:17 UTC (permalink / raw)
  To: nianfu.bai, gregkh, jirislaby; +Cc: linux-kernel

From: Zhenguo Zhao <Zhenguo.Zhao1@unisoc.com>

When n_gsm config "initiator=0",as requester,gsmld receives dlci SABM/DISC
control command frame,but send UA frame is error.

Example:
Gsmld receive dlc0 SABM frame "f9 03 3f 01 1c f9",now it sends UA
frame "f9 01 63 01 a3 f9",CR and PF bit are 0,but it should be set
1 from requster to initiator.

Kernel test log as follows:

Before modify

[  271.732031] c1 gsmld_receive: 00000000: f9 03 3f 01 1c f9
[  271.741719] c1 <-- 0) C: SABM(P)
[  271.749483] c1 gsmld_output: 00000000: f9 01 63 01 a3 f9
[  271.758337] c1 --> 0) R: UA(F)

After modify

[  261.233188] c0 gsmld_receive: 00000000: f9 03 3f 01 1c f9
[  261.242767] c0 <-- 0) C: SABM(P)
[  261.250497] c0 gsmld_output: 00000000: f9 03 73 01 d7 f9
[  261.259759] c0 --> 0) C: UA(P)

Signed-off-by: Zhenguo Zhao <Zhenguo.Zhao1@unisoc.com>
---
 drivers/tty/n_gsm.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
index becca2c..7aa10de 100644
--- a/drivers/tty/n_gsm.c
+++ b/drivers/tty/n_gsm.c
@@ -601,7 +601,7 @@ static void gsm_send(struct gsm_mux *gsm, int addr, int cr, int control)
 
 static inline void gsm_response(struct gsm_mux *gsm, int addr, int control)
 {
-	gsm_send(gsm, addr, 0, control);
+	gsm_send(gsm, addr, 1, control);
 }
 
 /**
@@ -1786,9 +1786,9 @@ static void gsm_queue(struct gsm_mux *gsm)
 		if (dlci == NULL)
 			return;
 		if (dlci->dead)
-			gsm_response(gsm, address, DM);
+			gsm_response(gsm, address, DM|PF);
 		else {
-			gsm_response(gsm, address, UA);
+			gsm_response(gsm, address, UA|PF);
 			gsm_dlci_open(dlci);
 		}
 		break;
@@ -1796,11 +1796,11 @@ static void gsm_queue(struct gsm_mux *gsm)
 		if (cr == 1)
 			goto invalid;
 		if (dlci == NULL || dlci->state == DLCI_CLOSED) {
-			gsm_response(gsm, address, DM);
+			gsm_response(gsm, address, DM|PF);
 			return;
 		}
 		/* Real close complete */
-		gsm_response(gsm, address, UA);
+		gsm_response(gsm, address, UA|PF);
 		gsm_dlci_close(dlci);
 		break;
 	case UA:
-- 
1.9.1


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 4/8] tty: n_gsm: Modify CR,PF bit printk info when config requester
  2021-08-20 12:17 [PATCH 1/8] tty: n_gsm: Add some instructions and code for requester Zhenguo Zhao
  2021-08-20 12:17 ` [PATCH 2/8] tty: n_gsm: Modify cr bit value when config requester Zhenguo Zhao
  2021-08-20 12:17 ` [PATCH 3/8] tty: n_gsm: Modify CR,PF bit " Zhenguo Zhao
@ 2021-08-20 12:17 ` Zhenguo Zhao
  2021-08-20 12:17 ` [PATCH 5/8] tty: n_gsm: Delete gsm_disconnect " Zhenguo Zhao
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Zhenguo Zhao @ 2021-08-20 12:17 UTC (permalink / raw)
  To: nianfu.bai, gregkh, jirislaby; +Cc: linux-kernel

From: Zhenguo Zhao <Zhenguo.Zhao1@unisoc.com>

When n_gsm config "initiator=0",as requester,gsmld receives dlci SABM/DISC
control command frame,UA frame printk info is error.

Example:
Gsmld send UA frame "f9 03 73 01 d7 f9",but CR,PF bit printk info
looks like error.

Kernel test log as follows:

Before modify

[   78.837626] c0 gsmld_receive: 00000000: f9 03 3f 01 1c f9
[   78.846356] c0 <-- 0) C: SABM(P)
[   78.854021] c0 gsmld_output: 00000000: f9 03 73 01 d7 f9
[   78.862574] c0 --> 0) C: UA(P)

After modify

[  261.233188] c0 gsmld_receive: 00000000: f9 03 3f 01 1c f9
[  261.242767] c0 <-- 0) C: SABM(P)
[  261.250497] c0 gsmld_output: 00000000: f9 03 73 01 d7 f9
[  261.259759] c0 --> 0) R: UA(F)

Signed-off-by: Zhenguo Zhao <Zhenguo.Zhao1@unisoc.com>
---
 drivers/tty/n_gsm.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
index 7aa10de..e3e1be3 100644
--- a/drivers/tty/n_gsm.c
+++ b/drivers/tty/n_gsm.c
@@ -587,6 +587,10 @@ static void gsm_send(struct gsm_mux *gsm, int addr, int cr, int control)
 		return;
 	}
 	gsmld_output(gsm, cbuf, len);
+	if (!gsm->initiator) {
+		cr = cr & gsm->initiator;
+		control = control & ~PF;
+	}
 	gsm_print_packet("-->", addr, cr, control, NULL, 0);
 }
 
-- 
1.9.1


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 5/8] tty: n_gsm: Delete gsm_disconnect when config requester
  2021-08-20 12:17 [PATCH 1/8] tty: n_gsm: Add some instructions and code for requester Zhenguo Zhao
                   ` (2 preceding siblings ...)
  2021-08-20 12:17 ` [PATCH 4/8] tty: n_gsm: Modify CR,PF bit printk info " Zhenguo Zhao
@ 2021-08-20 12:17 ` Zhenguo Zhao
  2021-08-20 12:17 ` [PATCH 6/8] tty: n_gsm: Delete gsmtty open SABM frame " Zhenguo Zhao
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Zhenguo Zhao @ 2021-08-20 12:17 UTC (permalink / raw)
  To: nianfu.bai, gregkh, jirislaby; +Cc: linux-kernel

From: Zhenguo Zhao <Zhenguo.Zhao1@unisoc.com>

When n_gsm config "initiator=0",when gsmld config ,as requester ,it
doesn't need to send CLD frame data or SABM frame.

Example,when tty dev receive "AT+CMUX=0",it will change ldisc
n_tty to n_gsm,during config requester,gsmld output "7e 01 ef c3 aa 7e",
initiator maybe not want to receive the frame data.

[  154.666457] c1 Q>  0) R: UIH(F)
[  154.669514] c1 C3
[  154.671519] c1 gsmld_output: 00000000: 7e 01 ef c3 aa 7e
[  155.014874] c1 Q>  0) R: UIH(F)
[  155.018000] c1 C3
[  155.020046] c1 gsmld_output: 00000000: 7e 01 ef c3 aa 7e
[  155.364425] c1 Q>  0) R: UIH(F)
[  155.367546] c1 C3
[  155.369597] c1 gsmld_output: 00000000: 7e 01 ef c3 aa 7e

Signed-off-by: Zhenguo Zhao <Zhenguo.Zhao1@unisoc.com>
---
 drivers/tty/n_gsm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
index e3e1be3..9ded99a 100644
--- a/drivers/tty/n_gsm.c
+++ b/drivers/tty/n_gsm.c
@@ -2304,7 +2304,7 @@ static int gsm_config(struct gsm_mux *gsm, struct gsm_config *c)
 	 * configuration
 	 */
 
-	if (need_close || need_restart) {
+	if (gsm->initiator && (need_close || need_restart)) {
 		int ret;
 
 		ret = gsm_disconnect(gsm);
-- 
1.9.1


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 6/8] tty: n_gsm: Delete gsmtty open SABM frame when config requester
  2021-08-20 12:17 [PATCH 1/8] tty: n_gsm: Add some instructions and code for requester Zhenguo Zhao
                   ` (3 preceding siblings ...)
  2021-08-20 12:17 ` [PATCH 5/8] tty: n_gsm: Delete gsm_disconnect " Zhenguo Zhao
@ 2021-08-20 12:17 ` Zhenguo Zhao
  2021-08-20 12:17 ` [PATCH 7/8] tty: n_gsm: Modify gsmtty driver register method " Zhenguo Zhao
  2021-08-20 12:17 ` [PATCH 8/8] tty: n_gsm: Save dlci address open status " Zhenguo Zhao
  6 siblings, 0 replies; 8+ messages in thread
From: Zhenguo Zhao @ 2021-08-20 12:17 UTC (permalink / raw)
  To: nianfu.bai, gregkh, jirislaby; +Cc: linux-kernel

From: Zhenguo Zhao <Zhenguo.Zhao1@unisoc.com>

When n_gsm config "initiator=0",as requester ,it doesn't need to
send SABM frame data during gsmtty open.

Example,when gsmtty open,it will send SABM frame.for initiator,it
maybe not want to receive the frame.

[   88.410426] c1 gsmld_output: 00000000: f9 07 3f 01 de f9
[   88.420839] c1 --> 1) R: SABM(F)

Signed-off-by: Zhenguo Zhao <Zhenguo.Zhao1@unisoc.com>
---
 drivers/tty/n_gsm.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
index 9ded99a..8d56d3d 100644
--- a/drivers/tty/n_gsm.c
+++ b/drivers/tty/n_gsm.c
@@ -3001,6 +3001,7 @@ static int gsmtty_open(struct tty_struct *tty, struct file *filp)
 {
 	struct gsm_dlci *dlci = tty->driver_data;
 	struct tty_port *port = &dlci->port;
+	struct gsm_mux *gsm = dlci->gsm;
 
 	port->count++;
 	tty_port_tty_set(port, tty);
@@ -3010,7 +3011,8 @@ static int gsmtty_open(struct tty_struct *tty, struct file *filp)
 	   a DM straight back. This is ok as that will have caused a hangup */
 	tty_port_set_initialized(port, 1);
 	/* Start sending off SABM messages */
-	gsm_dlci_begin_open(dlci);
+	if (gsm->initiator)
+		gsm_dlci_begin_open(dlci);
 	/* And wait for virtual carrier */
 	return tty_port_block_til_ready(port, tty, filp);
 }
-- 
1.9.1


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 7/8] tty: n_gsm: Modify gsmtty driver register method when config requester
  2021-08-20 12:17 [PATCH 1/8] tty: n_gsm: Add some instructions and code for requester Zhenguo Zhao
                   ` (4 preceding siblings ...)
  2021-08-20 12:17 ` [PATCH 6/8] tty: n_gsm: Delete gsmtty open SABM frame " Zhenguo Zhao
@ 2021-08-20 12:17 ` Zhenguo Zhao
  2021-08-20 12:17 ` [PATCH 8/8] tty: n_gsm: Save dlci address open status " Zhenguo Zhao
  6 siblings, 0 replies; 8+ messages in thread
From: Zhenguo Zhao @ 2021-08-20 12:17 UTC (permalink / raw)
  To: nianfu.bai, gregkh, jirislaby; +Cc: linux-kernel

From: Zhenguo Zhao <Zhenguo.Zhao1@unisoc.com>

As requester,because n_gsm has no uevent report for application,the
application can't know dlci connect or disconnect.

The application will control every dlcl dev by uevent,when application
receive gsmtty0 dev remove uevent,it will close mux function,and change to
normal mode.

Example:

Before modify:

gsmld receive DLC0 DISC,no event report to application
gsmld receive DLC1 SABM,no event report to application
gsmld receive DLC1 DISC,no event report to application

After modify:

Receive DLC0 DISC,report "/devices/virtual/tty/gsmtty0" remove uevent

Receive DLC1 SABM,report "/devices/virtual/tty/gsmtty1" add uevent
Receive DLC1 DISC,report "/devices/virtual/tty/gsmtty1" remove uevent

Signed-off-by: Zhenguo Zhao <Zhenguo.Zhao1@unisoc.com>
---
 drivers/tty/n_gsm.c | 30 +++++++++++++++++++-----------
 1 file changed, 19 insertions(+), 11 deletions(-)

diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
index 8d56d3d..9001805 100644
--- a/drivers/tty/n_gsm.c
+++ b/drivers/tty/n_gsm.c
@@ -1433,6 +1433,8 @@ static void gsm_dlci_close(struct gsm_dlci *dlci)
 		kfifo_reset(&dlci->fifo);
 	} else
 		dlci->gsm->dead = true;
+	/* Unregister gsmtty driver,report gsmtty dev remove uevent for user */
+	tty_unregister_device(gsm_tty_driver, dlci->addr);
 	wake_up(&dlci->gsm->event);
 	/* A DLCI 0 close is a MUX termination so we need to kick that
 	   back to userspace somehow */
@@ -1454,6 +1456,8 @@ static void gsm_dlci_open(struct gsm_dlci *dlci)
 	dlci->state = DLCI_OPEN;
 	if (debug & 8)
 		pr_debug("DLCI %d goes open.\n", dlci->addr);
+	/* Register gsmtty driver,report gsmtty dev add uevent for user */
+	tty_register_device(gsm_tty_driver, dlci->addr, NULL);
 	wake_up(&dlci->gsm->event);
 }
 
@@ -2388,17 +2392,19 @@ static int gsmld_attach_gsm(struct tty_struct *tty, struct gsm_mux *gsm)
 	else {
 		/* Don't register device 0 - this is the control channel and not
 		   a usable tty interface */
-		base = mux_num_to_base(gsm); /* Base for this MUX */
-		for (i = 1; i < NUM_DLCI; i++) {
-			struct device *dev;
+		if (gsm->initiator) {
+			base = mux_num_to_base(gsm); /* Base for this MUX */
+			for (i = 1; i < NUM_DLCI; i++) {
+				struct device *dev;
 
-			dev = tty_register_device(gsm_tty_driver,
+				dev = tty_register_device(gsm_tty_driver,
 							base + i, NULL);
-			if (IS_ERR(dev)) {
-				for (i--; i >= 1; i--)
-					tty_unregister_device(gsm_tty_driver,
-								base + i);
-				return PTR_ERR(dev);
+				if (IS_ERR(dev)) {
+					for (i--; i >= 1; i--)
+						tty_unregister_device(gsm_tty_driver,
+									base + i);
+					return PTR_ERR(dev);
+				}
 			}
 		}
 	}
@@ -2420,8 +2426,10 @@ static void gsmld_detach_gsm(struct tty_struct *tty, struct gsm_mux *gsm)
 	int i;
 
 	WARN_ON(tty != gsm->tty);
-	for (i = 1; i < NUM_DLCI; i++)
-		tty_unregister_device(gsm_tty_driver, base + i);
+	if (gsm->initiator) {
+		for (i = 1; i < NUM_DLCI; i++)
+			tty_unregister_device(gsm_tty_driver, base + i);
+	}
 	gsm_cleanup_mux(gsm);
 	tty_kref_put(gsm->tty);
 	gsm->tty = NULL;
-- 
1.9.1


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 8/8] tty: n_gsm: Save dlci address open status when config requester
  2021-08-20 12:17 [PATCH 1/8] tty: n_gsm: Add some instructions and code for requester Zhenguo Zhao
                   ` (5 preceding siblings ...)
  2021-08-20 12:17 ` [PATCH 7/8] tty: n_gsm: Modify gsmtty driver register method " Zhenguo Zhao
@ 2021-08-20 12:17 ` Zhenguo Zhao
  6 siblings, 0 replies; 8+ messages in thread
From: Zhenguo Zhao @ 2021-08-20 12:17 UTC (permalink / raw)
  To: nianfu.bai, gregkh, jirislaby; +Cc: linux-kernel

From: Zhenguo Zhao <Zhenguo.Zhao1@unisoc.com>

When n_gsm config "initiator=0",as requester ,receive SABM frame,n_gsm
register gsmtty dev,and save dlci open address status,if receive DLC0
DISC or CLD frame,it can unregister the gsmtty dev by saving dlci address.

Signed-off-by: Zhenguo Zhao <Zhenguo.Zhao1@unisoc.com>
---
 drivers/tty/n_gsm.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 53 insertions(+), 4 deletions(-)

diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
index 9001805..0b52d78 100644
--- a/drivers/tty/n_gsm.c
+++ b/drivers/tty/n_gsm.c
@@ -271,6 +271,10 @@ struct gsm_mux {
 
 static struct tty_driver *gsm_tty_driver;
 
+/* Save dlci open address */
+static int addr_open[256] = { 0 };
+/* Save dlci open count */
+static int addr_cnt;
 /*
  *	This section of the driver logic implements the GSM encodings
  *	both the basic and the 'advanced'. Reliable transport is not
@@ -1181,6 +1185,7 @@ static void gsm_control_rls(struct gsm_mux *gsm, const u8 *data, int clen)
 }
 
 static void gsm_dlci_begin_close(struct gsm_dlci *dlci);
+static void gsm_dlci_close(struct gsm_dlci *dlci);
 
 /**
  *	gsm_control_message	-	DLCI 0 control processing
@@ -1199,15 +1204,28 @@ static void gsm_control_message(struct gsm_mux *gsm, unsigned int command,
 {
 	u8 buf[1];
 	unsigned long flags;
+	struct gsm_dlci *dlci;
+	int i;
+	int address;
 
 	switch (command) {
 	case CMD_CLD: {
-		struct gsm_dlci *dlci = gsm->dlci[0];
+		if (addr_cnt > 0) {
+			for (i = 0; i < addr_cnt; i++) {
+				address = addr_open[i];
+				dlci = gsm->dlci[address];
+				gsm_dlci_close(dlci);
+				addr_open[i] = 0;
+			}
+		}
 		/* Modem wishes to close down */
+		dlci = gsm->dlci[0];
 		if (dlci) {
 			dlci->dead = true;
 			gsm->dead = true;
-			gsm_dlci_begin_close(dlci);
+			gsm_dlci_close(dlci);
+			addr_cnt = 0;
+			gsm_response(gsm, 0, UA|PF);
 		}
 		}
 		break;
@@ -1756,6 +1774,7 @@ static void gsm_queue(struct gsm_mux *gsm)
 	struct gsm_dlci *dlci;
 	u8 cr;
 	int address;
+	int i, j, k, address_tmp;
 	/* We have to sneak a look at the packet body to do the FCS.
 	   A somewhat layering violation in the spec */
 
@@ -1798,6 +1817,11 @@ static void gsm_queue(struct gsm_mux *gsm)
 		else {
 			gsm_response(gsm, address, UA|PF);
 			gsm_dlci_open(dlci);
+			/* Save dlci open address */
+			if (address) {
+				addr_open[addr_cnt] = address;
+				addr_cnt++;
+			}
 		}
 		break;
 	case DISC|PF:
@@ -1808,8 +1832,33 @@ static void gsm_queue(struct gsm_mux *gsm)
 			return;
 		}
 		/* Real close complete */
-		gsm_response(gsm, address, UA|PF);
-		gsm_dlci_close(dlci);
+		if (!address) {
+			if (addr_cnt > 0) {
+				for (i = 0; i < addr_cnt; i++) {
+					address = addr_open[i];
+					dlci = gsm->dlci[address];
+					gsm_dlci_close(dlci);
+					addr_open[i] = 0;
+				}
+			}
+			dlci = gsm->dlci[0];
+			gsm_dlci_close(dlci);
+			addr_cnt = 0;
+			gsm_response(gsm, 0, UA|PF);
+		} else {
+			gsm_response(gsm, address, UA|PF);
+			gsm_dlci_close(dlci);
+			/* clear dlci address */
+			for (j = 0; j < addr_cnt; j++) {
+				address_tmp = addr_open[j];
+				if (address_tmp == address) {
+					for (k = j; k < addr_cnt; k++)
+						addr_open[k] = addr_open[k+1];
+				addr_cnt--;
+				break;
+				}
+			}
+		}
 		break;
 	case UA:
 	case UA|PF:
-- 
1.9.1


^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2021-08-20 12:19 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-20 12:17 [PATCH 1/8] tty: n_gsm: Add some instructions and code for requester Zhenguo Zhao
2021-08-20 12:17 ` [PATCH 2/8] tty: n_gsm: Modify cr bit value when config requester Zhenguo Zhao
2021-08-20 12:17 ` [PATCH 3/8] tty: n_gsm: Modify CR,PF bit " Zhenguo Zhao
2021-08-20 12:17 ` [PATCH 4/8] tty: n_gsm: Modify CR,PF bit printk info " Zhenguo Zhao
2021-08-20 12:17 ` [PATCH 5/8] tty: n_gsm: Delete gsm_disconnect " Zhenguo Zhao
2021-08-20 12:17 ` [PATCH 6/8] tty: n_gsm: Delete gsmtty open SABM frame " Zhenguo Zhao
2021-08-20 12:17 ` [PATCH 7/8] tty: n_gsm: Modify gsmtty driver register method " Zhenguo Zhao
2021-08-20 12:17 ` [PATCH 8/8] tty: n_gsm: Save dlci address open status " Zhenguo Zhao

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).