Commit afe3154b authored by Daniel Starke's avatar Daniel Starke Committed by Greg Kroah-Hartman

tty: n_gsm: add ioctl for DLC config via ldisc handle

The application which initializes the n_gsm ldisc may like to set
individual default parameters for each DLCI or take over of the application
specific DLCI configuration completely. This is currently not possible.
It is either possible to set common default parameters for all DLCIs or let
the user application set its DLCI specific configuration parameters.

Add support of GSMIOC_GETCONF_DLCI and GSMIOC_SETCONF_DLCI for the n_gsm
ldisc handle to support DLCI specific parameter configuration upfront.

Add a code example for this use case to the n_gsm documentation.
Signed-off-by: default avatarDaniel Starke <daniel.starke@siemens.com>
Link: https://lore.kernel.org/r/20230315105354.6234-3-daniel.starke@siemens.comSigned-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 8629745c
...@@ -47,6 +47,7 @@ Config Initiator ...@@ -47,6 +47,7 @@ Config Initiator
int ldisc = N_GSM0710; int ldisc = N_GSM0710;
struct gsm_config c; struct gsm_config c;
struct gsm_config_ext ce; struct gsm_config_ext ce;
struct gsm_dlci_config dc;
struct termios configuration; struct termios configuration;
uint32_t first; uint32_t first;
...@@ -83,6 +84,13 @@ Config Initiator ...@@ -83,6 +84,13 @@ Config Initiator
c.mtu = 127; c.mtu = 127;
/* set the new configuration */ /* set the new configuration */
ioctl(fd, GSMIOC_SETCONF, &c); ioctl(fd, GSMIOC_SETCONF, &c);
/* get DLC 1 configuration */
dc.channel = 1;
ioctl(fd, GSMIOC_GETCONF_DLCI, &dc);
/* the first user channel gets a higher priority */
dc.priority = 1;
/* set the new DLC 1 specific configuration */
ioctl(fd, GSMIOC_SETCONF_DLCI, &dc);
/* get first gsmtty device node */ /* get first gsmtty device node */
ioctl(fd, GSMIOC_GETFIRST, &first); ioctl(fd, GSMIOC_GETFIRST, &first);
printf("first muxed line: /dev/gsmtty%i\n", first); printf("first muxed line: /dev/gsmtty%i\n", first);
...@@ -136,6 +144,7 @@ Config Requester ...@@ -136,6 +144,7 @@ Config Requester
int ldisc = N_GSM0710; int ldisc = N_GSM0710;
struct gsm_config c; struct gsm_config c;
struct gsm_config_ext ce; struct gsm_config_ext ce;
struct gsm_dlci_config dc;
struct termios configuration; struct termios configuration;
uint32_t first; uint32_t first;
...@@ -165,6 +174,13 @@ Config Requester ...@@ -165,6 +174,13 @@ Config Requester
c.mtu = 127; c.mtu = 127;
/* set the new configuration */ /* set the new configuration */
ioctl(fd, GSMIOC_SETCONF, &c); ioctl(fd, GSMIOC_SETCONF, &c);
/* get DLC 1 configuration */
dc.channel = 1;
ioctl(fd, GSMIOC_GETCONF_DLCI, &dc);
/* the first user channel gets a higher priority */
dc.priority = 1;
/* set the new DLC 1 specific configuration */
ioctl(fd, GSMIOC_SETCONF_DLCI, &dc);
/* get first gsmtty device node */ /* get first gsmtty device node */
ioctl(fd, GSMIOC_GETFIRST, &first); ioctl(fd, GSMIOC_GETFIRST, &first);
printf("first muxed line: /dev/gsmtty%i\n", first); printf("first muxed line: /dev/gsmtty%i\n", first);
......
...@@ -3716,7 +3716,9 @@ static int gsmld_ioctl(struct tty_struct *tty, unsigned int cmd, ...@@ -3716,7 +3716,9 @@ static int gsmld_ioctl(struct tty_struct *tty, unsigned int cmd,
{ {
struct gsm_config c; struct gsm_config c;
struct gsm_config_ext ce; struct gsm_config_ext ce;
struct gsm_dlci_config dc;
struct gsm_mux *gsm = tty->disc_data; struct gsm_mux *gsm = tty->disc_data;
struct gsm_dlci *dlci;
unsigned int base; unsigned int base;
switch (cmd) { switch (cmd) {
...@@ -3741,6 +3743,33 @@ static int gsmld_ioctl(struct tty_struct *tty, unsigned int cmd, ...@@ -3741,6 +3743,33 @@ static int gsmld_ioctl(struct tty_struct *tty, unsigned int cmd,
if (copy_from_user(&ce, (void __user *)arg, sizeof(ce))) if (copy_from_user(&ce, (void __user *)arg, sizeof(ce)))
return -EFAULT; return -EFAULT;
return gsm_config_ext(gsm, &ce); return gsm_config_ext(gsm, &ce);
case GSMIOC_GETCONF_DLCI:
if (copy_from_user(&dc, (void __user *)arg, sizeof(dc)))
return -EFAULT;
if (dc.channel == 0 || dc.channel >= NUM_DLCI)
return -EINVAL;
dlci = gsm->dlci[dc.channel];
if (!dlci) {
dlci = gsm_dlci_alloc(gsm, dc.channel);
if (!dlci)
return -ENOMEM;
}
gsm_dlci_copy_config_values(dlci, &dc);
if (copy_to_user((void __user *)arg, &dc, sizeof(dc)))
return -EFAULT;
return 0;
case GSMIOC_SETCONF_DLCI:
if (copy_from_user(&dc, (void __user *)arg, sizeof(dc)))
return -EFAULT;
if (dc.channel == 0 || dc.channel >= NUM_DLCI)
return -EINVAL;
dlci = gsm->dlci[dc.channel];
if (!dlci) {
dlci = gsm_dlci_alloc(gsm, dc.channel);
if (!dlci)
return -ENOMEM;
}
return gsm_dlci_config(dlci, &dc, 0);
default: default:
return n_tty_ioctl_helper(tty, cmd, arg); return n_tty_ioctl_helper(tty, cmd, arg);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment