2010-07-06 00:22:01

by Tilman Schmidt

[permalink] [raw]
Subject: [PATCH 00/11] ISDN patches for 2.6.36

Karsten, David,

following are a series of patches to the Gigaset driver I'd like
to see included in kernel release 2.6.36.

Thanks,
Tilman

Tilman Schmidt (11):
isdn/gigaset: make tty write buffer limit consistent
isdn/gigaset: avoid copying AT commands twice
isdn/gigaset: ignore irrelevant device responses
isdn/gigaset: drop debug check on isochronous write
isdn/gigaset: improve CAPI message debugging
isdn/gigaset: handle Supplementary Service Listen
isdn/gigaset: remove obsolete compile time options
isdn/gigaset: reduce syslog spam
isdn/gigaset: fix leaks in error path
isdn/gigaset: document dial-out number format
isdn/gigaset: remove EXPERIMENTAL tag from GIGASET_CAPI option

Documentation/isdn/README.gigaset | 117 +++++++++++++++++------------
drivers/isdn/gigaset/Kconfig | 4 -
drivers/isdn/gigaset/bas-gigaset.c | 69 ++---------------
drivers/isdn/gigaset/capi.c | 70 ++++++++++++-----
drivers/isdn/gigaset/common.c | 2
drivers/isdn/gigaset/ev-layer.c | 148 ++++++++++++-------------------------
drivers/isdn/gigaset/gigaset.h | 16 ----
drivers/isdn/gigaset/i4l.c | 4 -
drivers/isdn/gigaset/interface.c | 37 +++++++--
drivers/isdn/gigaset/ser-gigaset.c | 27 +-----
drivers/isdn/gigaset/usb-gigaset.c | 29 +------
11 files changed, 226 insertions(+), 297 deletions(-)


2010-07-06 00:18:57

by Tilman Schmidt

[permalink] [raw]
Subject: [PATCH 01/11] isdn/gigaset: adjust usb_gigaset tty write buffer limit

The usb_gigaset driver's write buffer limit was different from those
of the others for no good reason. Set it to the same value, derived
from the Siemens documentation.

Impact: cosmetic
Signed-off-by: Tilman Schmidt <[email protected]>
---
drivers/isdn/gigaset/usb-gigaset.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/isdn/gigaset/usb-gigaset.c b/drivers/isdn/gigaset/usb-gigaset.c
index 76dbb20..f65cf7d 100644
--- a/drivers/isdn/gigaset/usb-gigaset.c
+++ b/drivers/isdn/gigaset/usb-gigaset.c
@@ -39,7 +39,8 @@ MODULE_PARM_DESC(cidmode, "Call-ID mode");
#define GIGASET_MODULENAME "usb_gigaset"
#define GIGASET_DEVNAME "ttyGU"

-#define IF_WRITEBUF 2000 /* arbitrary limit */
+/* length limit according to Siemens 3070usb-protokoll.doc ch. 2.1 */
+#define IF_WRITEBUF 264

/* Values for the Gigaset M105 Data */
#define USB_M105_VENDOR_ID 0x0681
--
1.6.5.3.298.g39add

2010-07-06 00:19:09

by Tilman Schmidt

[permalink] [raw]
Subject: [PATCH 03/11] isdn/gigaset: ignore irrelevant device responses

Downgrade the Gigaset driver's reaction to unknown AT responses from
the device from warning to debug level, and remove the handling of
some device responses which aren't relevant for the driver's
operation.

Impact: cleanup
Signed-off-by: Tilman Schmidt <[email protected]>
---
drivers/isdn/gigaset/ev-layer.c | 67 ++++++++------------------------------
drivers/isdn/gigaset/gigaset.h | 5 +--
2 files changed, 16 insertions(+), 56 deletions(-)

diff --git a/drivers/isdn/gigaset/ev-layer.c b/drivers/isdn/gigaset/ev-layer.c
index 0d5984a..657757b 100644
--- a/drivers/isdn/gigaset/ev-layer.c
+++ b/drivers/isdn/gigaset/ev-layer.c
@@ -35,53 +35,40 @@
#define RT_RING 2
#define RT_NUMBER 3
#define RT_STRING 4
-#define RT_HEX 5
#define RT_ZCAU 6

/* Possible ASCII responses */
#define RSP_OK 0
-#define RSP_BUSY 1
-#define RSP_CONNECT 2
+#define RSP_ERROR 1
#define RSP_ZGCI 3
#define RSP_RING 4
-#define RSP_ZAOC 5
-#define RSP_ZCSTR 6
-#define RSP_ZCFGT 7
-#define RSP_ZCFG 8
-#define RSP_ZCCR 9
-#define RSP_EMPTY 10
-#define RSP_ZLOG 11
-#define RSP_ZCAU 12
-#define RSP_ZMWI 13
-#define RSP_ZABINFO 14
-#define RSP_ZSMLSTCHG 15
+#define RSP_ZVLS 5
+#define RSP_ZCAU 6
+
+/* responses with values to store in at_state */
+/* - numeric */
#define RSP_VAR 100
#define RSP_ZSAU (RSP_VAR + VAR_ZSAU)
#define RSP_ZDLE (RSP_VAR + VAR_ZDLE)
-#define RSP_ZVLS (RSP_VAR + VAR_ZVLS)
#define RSP_ZCTP (RSP_VAR + VAR_ZCTP)
+/* - string */
#define RSP_STR (RSP_VAR + VAR_NUM)
#define RSP_NMBR (RSP_STR + STR_NMBR)
#define RSP_ZCPN (RSP_STR + STR_ZCPN)
#define RSP_ZCON (RSP_STR + STR_ZCON)
#define RSP_ZBC (RSP_STR + STR_ZBC)
#define RSP_ZHLC (RSP_STR + STR_ZHLC)
-#define RSP_ERROR -1 /* ERROR */
+
#define RSP_WRONG_CID -2 /* unknown cid in cmd */
-#define RSP_UNKNOWN -4 /* unknown response */
-#define RSP_FAIL -5 /* internal error */
#define RSP_INVAL -6 /* invalid response */
+#define RSP_NODEV -9 /* device not connected */

#define RSP_NONE -19
#define RSP_STRING -20
#define RSP_NULL -21
-#define RSP_RETRYFAIL -22
-#define RSP_RETRY -23
-#define RSP_SKIP -24
#define RSP_INIT -27
#define RSP_ANY -26
#define RSP_LAST -28
-#define RSP_NODEV -9

/* actions for process_response */
#define ACT_NOTHING 0
@@ -259,13 +246,6 @@ struct reply_t gigaset_tab_nocid[] =

/* misc. */
{RSP_ERROR, -1, -1, -1, -1, -1, {ACT_ERROR} },
-{RSP_ZCFGT, -1, -1, -1, -1, -1, {ACT_DEBUG} },
-{RSP_ZCFG, -1, -1, -1, -1, -1, {ACT_DEBUG} },
-{RSP_ZLOG, -1, -1, -1, -1, -1, {ACT_DEBUG} },
-{RSP_ZMWI, -1, -1, -1, -1, -1, {ACT_DEBUG} },
-{RSP_ZABINFO, -1, -1, -1, -1, -1, {ACT_DEBUG} },
-{RSP_ZSMLSTCHG, -1, -1, -1, -1, -1, {ACT_DEBUG} },
-
{RSP_ZCAU, -1, -1, -1, -1, -1, {ACT_ZCAU} },
{RSP_NONE, -1, -1, -1, -1, -1, {ACT_DEBUG} },
{RSP_ANY, -1, -1, -1, -1, -1, {ACT_WARN} },
@@ -361,10 +341,6 @@ struct reply_t gigaset_tab_cid[] =

/* misc. */
{RSP_ZCON, -1, -1, -1, -1, -1, {ACT_DEBUG} },
-{RSP_ZCCR, -1, -1, -1, -1, -1, {ACT_DEBUG} },
-{RSP_ZAOC, -1, -1, -1, -1, -1, {ACT_DEBUG} },
-{RSP_ZCSTR, -1, -1, -1, -1, -1, {ACT_DEBUG} },
-
{RSP_ZCAU, -1, -1, -1, -1, -1, {ACT_ZCAU} },
{RSP_NONE, -1, -1, -1, -1, -1, {ACT_DEBUG} },
{RSP_ANY, -1, -1, -1, -1, -1, {ACT_WARN} },
@@ -387,20 +363,11 @@ static const struct resp_type_t {
{"ZVLS", RSP_ZVLS, RT_NUMBER},
{"ZCTP", RSP_ZCTP, RT_NUMBER},
{"ZDLE", RSP_ZDLE, RT_NUMBER},
- {"ZCFGT", RSP_ZCFGT, RT_NUMBER},
- {"ZCCR", RSP_ZCCR, RT_NUMBER},
- {"ZMWI", RSP_ZMWI, RT_NUMBER},
{"ZHLC", RSP_ZHLC, RT_STRING},
{"ZBC", RSP_ZBC, RT_STRING},
{"NMBR", RSP_NMBR, RT_STRING},
{"ZCPN", RSP_ZCPN, RT_STRING},
{"ZCON", RSP_ZCON, RT_STRING},
- {"ZAOC", RSP_ZAOC, RT_STRING},
- {"ZCSTR", RSP_ZCSTR, RT_STRING},
- {"ZCFG", RSP_ZCFG, RT_HEX},
- {"ZLOG", RSP_ZLOG, RT_NOTHING},
- {"ZABINFO", RSP_ZABINFO, RT_NOTHING},
- {"ZSMLSTCHG", RSP_ZSMLSTCHG, RT_NOTHING},
{NULL, 0, 0}
};

@@ -588,10 +555,10 @@ void gigaset_handle_modem_response(struct cardstate *cs)
break;

if (!rt->response) {
- event->type = RSP_UNKNOWN;
- dev_warn(cs->dev,
- "unknown modem response: %s\n",
- argv[curarg]);
+ event->type = RSP_NONE;
+ gig_dbg(DEBUG_EVENT,
+ "unknown modem response: '%s'\n",
+ argv[curarg]);
break;
}

@@ -655,14 +622,8 @@ void gigaset_handle_modem_response(struct cardstate *cs)
curarg = params - 1;
break;
case RT_NUMBER:
- case RT_HEX:
if (curarg < params) {
- if (param_type == RT_HEX)
- event->parameter =
- isdn_gethex(argv[curarg]);
- else
- event->parameter =
- isdn_getnum(argv[curarg]);
+ event->parameter = isdn_getnum(argv[curarg]);
++curarg;
} else
event->parameter = -1;
diff --git a/drivers/isdn/gigaset/gigaset.h b/drivers/isdn/gigaset/gigaset.h
index 1d0999b..add3d0c 100644
--- a/drivers/isdn/gigaset/gigaset.h
+++ b/drivers/isdn/gigaset/gigaset.h
@@ -193,9 +193,8 @@ void gigaset_dbg_buffer(enum debuglevel level, const unsigned char *msg,
/* variables in struct at_state_t */
#define VAR_ZSAU 0
#define VAR_ZDLE 1
-#define VAR_ZVLS 2
-#define VAR_ZCTP 3
-#define VAR_NUM 4
+#define VAR_ZCTP 2
+#define VAR_NUM 3

#define STR_NMBR 0
#define STR_ZCPN 1
--
1.6.5.3.298.g39add

2010-07-06 00:19:13

by Tilman Schmidt

[permalink] [raw]
Subject: [PATCH 04/11] isdn/gigaset: drop debug check on isochronous write

With CONFIG_GIGASET_DEBUG set, every isochronous USB frame after
an erroneous one was checked for more errors. This produced only
noise messages in practice, so drop it.

Impact: cleanup
Signed-off-by: Tilman Schmidt <[email protected]>
---
drivers/isdn/gigaset/bas-gigaset.c | 18 ------------------
1 files changed, 0 insertions(+), 18 deletions(-)

diff --git a/drivers/isdn/gigaset/bas-gigaset.c b/drivers/isdn/gigaset/bas-gigaset.c
index 2dab531..0ded364 100644
--- a/drivers/isdn/gigaset/bas-gigaset.c
+++ b/drivers/isdn/gigaset/bas-gigaset.c
@@ -1188,24 +1188,6 @@ static void write_iso_tasklet(unsigned long data)
break;
}
}
-#ifdef CONFIG_GIGASET_DEBUG
- /* check assumption on remaining frames */
- for (; i < BAS_NUMFRAMES; i++) {
- ifd = &urb->iso_frame_desc[i];
- if (ifd->status != -EINPROGRESS
- || ifd->actual_length != 0) {
- dev_warn(cs->dev,
- "isochronous write: frame %d: %s, "
- "%d of %d bytes sent\n",
- i, get_usb_statmsg(ifd->status),
- ifd->actual_length, ifd->length);
- offset = (ifd->offset +
- ifd->actual_length)
- % BAS_OUTBUFSIZE;
- break;
- }
- }
-#endif
break;
case -EPIPE: /* stall - probably underrun */
dev_err(cs->dev, "isochronous write stalled\n");
--
1.6.5.3.298.g39add

2010-07-06 00:19:19

by Tilman Schmidt

[permalink] [raw]
Subject: [PATCH 05/11] isdn/gigaset: improve CAPI message debugging

Provide better control of debugging output for DATA_B3 CAPI messages
which tend to occur very frequently.

Impact: logging
Signed-off-by: Tilman Schmidt <[email protected]>
---
drivers/isdn/gigaset/capi.c | 27 ++++++++++++++++-----------
1 files changed, 16 insertions(+), 11 deletions(-)

diff --git a/drivers/isdn/gigaset/capi.c b/drivers/isdn/gigaset/capi.c
index c38750c..ff074e9 100644
--- a/drivers/isdn/gigaset/capi.c
+++ b/drivers/isdn/gigaset/capi.c
@@ -270,9 +270,13 @@ static inline void dump_rawmsg(enum debuglevel level, const char *tag,
kfree(dbgline);
if (CAPIMSG_COMMAND(data) == CAPI_DATA_B3 &&
(CAPIMSG_SUBCOMMAND(data) == CAPI_REQ ||
- CAPIMSG_SUBCOMMAND(data) == CAPI_IND) &&
- CAPIMSG_DATALEN(data) > 0) {
+ CAPIMSG_SUBCOMMAND(data) == CAPI_IND)) {
l = CAPIMSG_DATALEN(data);
+ gig_dbg(level, " DataLength=%d", l);
+ if (l <= 0 || !(gigaset_debuglevel & DEBUG_LLDATA))
+ return;
+ if (l > 64)
+ l = 64; /* arbitrary limit */
dbgline = kmalloc(3*l, GFP_ATOMIC);
if (!dbgline)
return;
@@ -384,7 +388,7 @@ void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *dskb)

/* don't send further B3 messages if disconnected */
if (bcs->apconnstate < APCONN_ACTIVE) {
- gig_dbg(DEBUG_LLDATA, "disconnected, discarding ack");
+ gig_dbg(DEBUG_MCMD, "disconnected, discarding ack");
return;
}

@@ -428,7 +432,7 @@ void gigaset_skb_rcvd(struct bc_state *bcs, struct sk_buff *skb)

/* don't send further B3 messages if disconnected */
if (bcs->apconnstate < APCONN_ACTIVE) {
- gig_dbg(DEBUG_LLDATA, "disconnected, discarding data");
+ gig_dbg(DEBUG_MCMD, "disconnected, discarding data");
dev_kfree_skb_any(skb);
return;
}
@@ -454,7 +458,7 @@ void gigaset_skb_rcvd(struct bc_state *bcs, struct sk_buff *skb)
/* Data64 parameter not present */

/* emit message */
- dump_rawmsg(DEBUG_LLDATA, "DATA_B3_IND", skb->data);
+ dump_rawmsg(DEBUG_MCMD, __func__, skb->data);
capi_ctr_handle_message(&iif->ctr, ap->id, skb);
}
EXPORT_SYMBOL_GPL(gigaset_skb_rcvd);
@@ -978,6 +982,9 @@ static void gigaset_register_appl(struct capi_ctr *ctr, u16 appl,
struct cardstate *cs = ctr->driverdata;
struct gigaset_capi_appl *ap;

+ gig_dbg(DEBUG_CMD, "%s [%u] l3cnt=%u blkcnt=%u blklen=%u",
+ __func__, appl, rp->level3cnt, rp->datablkcnt, rp->datablklen);
+
list_for_each_entry(ap, &iif->appls, ctrlist)
if (ap->id == appl) {
dev_notice(cs->dev,
@@ -1062,6 +1069,8 @@ static void gigaset_release_appl(struct capi_ctr *ctr, u16 appl)
struct gigaset_capi_appl *ap, *tmp;
unsigned ch;

+ gig_dbg(DEBUG_CMD, "%s [%u]", __func__, appl);
+
list_for_each_entry_safe(ap, tmp, &iif->appls, ctrlist)
if (ap->id == appl) {
/* remove from any channels */
@@ -1951,11 +1960,7 @@ static void do_data_b3_req(struct gigaset_capi_ctr *iif,
u16 handle = CAPIMSG_HANDLE_REQ(skb->data);

/* frequent message, avoid _cmsg overhead */
- dump_rawmsg(DEBUG_LLDATA, "DATA_B3_REQ", skb->data);
-
- gig_dbg(DEBUG_LLDATA,
- "Receiving data from LL (ch: %d, flg: %x, sz: %d|%d)",
- channel, flags, msglen, datalen);
+ dump_rawmsg(DEBUG_MCMD, __func__, skb->data);

/* check parameters */
if (channel == 0 || channel > cs->channels || ncci != 1) {
@@ -2064,7 +2069,7 @@ static void do_data_b3_resp(struct gigaset_capi_ctr *iif,
struct gigaset_capi_appl *ap,
struct sk_buff *skb)
{
- dump_rawmsg(DEBUG_LLDATA, __func__, skb->data);
+ dump_rawmsg(DEBUG_MCMD, __func__, skb->data);
dev_kfree_skb_any(skb);
}

--
1.6.5.3.298.g39add

2010-07-06 00:19:26

by Tilman Schmidt

[permalink] [raw]
Subject: [PATCH 06/11] isdn/gigaset: handle Supplementary Service Listen

Add minimal handling for the non-optional CAPI FACILITY_REQ
Supplementary Service function Listen.

Impact: bugfix
Signed-off-by: Tilman Schmidt <[email protected]>
---
drivers/isdn/gigaset/capi.c | 27 ++++++++++++++++++++++++++-
1 files changed, 26 insertions(+), 1 deletions(-)

diff --git a/drivers/isdn/gigaset/capi.c b/drivers/isdn/gigaset/capi.c
index ff074e9..3714aef 100644
--- a/drivers/isdn/gigaset/capi.c
+++ b/drivers/isdn/gigaset/capi.c
@@ -45,6 +45,7 @@
#define CAPI_FACILITY_LI 0x0005

#define CAPI_SUPPSVC_GETSUPPORTED 0x0000
+#define CAPI_SUPPSVC_LISTEN 0x0001

/* missing from capiutil.h */
#define CAPIMSG_PLCI_PART(m) CAPIMSG_U8(m, 9)
@@ -1151,7 +1152,7 @@ static void do_facility_req(struct gigaset_capi_ctr *iif,
case CAPI_FACILITY_SUPPSVC:
/* decode Function parameter */
pparam = cmsg->FacilityRequestParameter;
- if (pparam == NULL || *pparam < 2) {
+ if (pparam == NULL || pparam[0] < 2) {
dev_notice(cs->dev, "%s: %s missing\n", "FACILITY_REQ",
"Facility Request Parameter");
send_conf(iif, ap, skb, CapiIllMessageParmCoding);
@@ -1168,8 +1169,32 @@ static void do_facility_req(struct gigaset_capi_ctr *iif,
/* Supported Services: none */
capimsg_setu32(confparam, 6, 0);
break;
+ case CAPI_SUPPSVC_LISTEN:
+ if (pparam[0] < 7 || pparam[3] < 4) {
+ dev_notice(cs->dev, "%s: %s missing\n",
+ "FACILITY_REQ", "Notification Mask");
+ send_conf(iif, ap, skb,
+ CapiIllMessageParmCoding);
+ return;
+ }
+ if (CAPIMSG_U32(pparam, 4) != 0) {
+ dev_notice(cs->dev,
+ "%s: unsupported supplementary service notification mask 0x%x\n",
+ "FACILITY_REQ", CAPIMSG_U32(pparam, 4));
+ info = CapiFacilitySpecificFunctionNotSupported;
+ confparam[3] = 2; /* length */
+ capimsg_setu16(confparam, 4,
+ CapiSupplementaryServiceNotSupported);
+ }
+ info = CapiSuccess;
+ confparam[3] = 2; /* length */
+ capimsg_setu16(confparam, 4, CapiSuccess);
+ break;
/* ToDo: add supported services */
default:
+ dev_notice(cs->dev,
+ "%s: unsupported supplementary service function 0x%04x\n",
+ "FACILITY_REQ", function);
info = CapiFacilitySpecificFunctionNotSupported;
/* Supplementary Service specific parameter */
confparam[3] = 2; /* length */
--
1.6.5.3.298.g39add

2010-07-06 00:19:37

by Tilman Schmidt

[permalink] [raw]
Subject: [PATCH 07/11] isdn/gigaset: remove obsolete compile time options

Remove compile time options in the Gigaset ISDN driver that aren't
going to be changed anymore, and an obsolete FIXME comment.

Impact: cleanup
Signed-off-by: Tilman Schmidt <[email protected]>
---
drivers/isdn/gigaset/common.c | 2 --
drivers/isdn/gigaset/ev-layer.c | 6 ------
drivers/isdn/gigaset/gigaset.h | 7 -------
drivers/isdn/gigaset/i4l.c | 2 --
drivers/isdn/gigaset/interface.c | 1 -
5 files changed, 0 insertions(+), 18 deletions(-)

diff --git a/drivers/isdn/gigaset/common.c b/drivers/isdn/gigaset/common.c
index 5d4befb..3ca561e 100644
--- a/drivers/isdn/gigaset/common.c
+++ b/drivers/isdn/gigaset/common.c
@@ -791,8 +791,6 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels,
spin_unlock_irqrestore(&cs->lock, flags);
setup_timer(&cs->timer, timer_tick, (unsigned long) cs);
cs->timer.expires = jiffies + msecs_to_jiffies(GIG_TICK);
- /* FIXME: can jiffies increase too much until the timer is added?
- * Same problem(?) with mod_timer() in timer_tick(). */
add_timer(&cs->timer);

gig_dbg(DEBUG_INIT, "cs initialized");
diff --git a/drivers/isdn/gigaset/ev-layer.c b/drivers/isdn/gigaset/ev-layer.c
index 657757b..a230ba7 100644
--- a/drivers/isdn/gigaset/ev-layer.c
+++ b/drivers/isdn/gigaset/ev-layer.c
@@ -1809,19 +1809,13 @@ static void process_command_flags(struct cardstate *cs)
gig_dbg(DEBUG_EVENT, "Scheduling PC_CIDMODE");
cs->commands_pending = 1;
return;
-#ifdef GIG_MAYINITONDIAL
case M_UNKNOWN:
schedule_init(cs, MS_INIT);
return;
-#endif
}
bcs->at_state.pending_commands &= ~PC_CID;
cs->curchannel = bcs->channel;
-#ifdef GIG_RETRYCID
cs->retry_count = 2;
-#else
- cs->retry_count = 1;
-#endif
schedule_sequence(cs, &cs->at_state, SEQ_CID);
return;
}
diff --git a/drivers/isdn/gigaset/gigaset.h b/drivers/isdn/gigaset/gigaset.h
index ba9547b..a69512f 100644
--- a/drivers/isdn/gigaset/gigaset.h
+++ b/drivers/isdn/gigaset/gigaset.h
@@ -46,13 +46,6 @@

#define RBUFSIZE 8192

-/* compile time options */
-#define GIG_MAJOR 0
-
-#define GIG_MAYINITONDIAL
-#define GIG_RETRYCID
-#define GIG_X75
-
#define GIG_TICK 100 /* in milliseconds */

/* timeout values (unit: 1 sec) */
diff --git a/drivers/isdn/gigaset/i4l.c b/drivers/isdn/gigaset/i4l.c
index f01c3c2..1d084bb 100644
--- a/drivers/isdn/gigaset/i4l.c
+++ b/drivers/isdn/gigaset/i4l.c
@@ -643,9 +643,7 @@ int gigaset_isdn_regdev(struct cardstate *cs, const char *isdnid)
iif->maxbufsize = MAX_BUF_SIZE;
iif->features = ISDN_FEATURE_L2_TRANS |
ISDN_FEATURE_L2_HDLC |
-#ifdef GIG_X75
ISDN_FEATURE_L2_X75I |
-#endif
ISDN_FEATURE_L3_TRANS |
ISDN_FEATURE_P_EURO;
iif->hl_hdrlen = HW_HDR_LEN; /* Area for storing ack */
diff --git a/drivers/isdn/gigaset/interface.c b/drivers/isdn/gigaset/interface.c
index f45d686..bb710d1 100644
--- a/drivers/isdn/gigaset/interface.c
+++ b/drivers/isdn/gigaset/interface.c
@@ -677,7 +677,6 @@ void gigaset_if_initdriver(struct gigaset_driver *drv, const char *procname,
goto enomem;

tty->magic = TTY_DRIVER_MAGIC,
- tty->major = GIG_MAJOR,
tty->type = TTY_DRIVER_TYPE_SERIAL,
tty->subtype = SERIAL_TYPE_NORMAL,
tty->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
--
1.6.5.3.298.g39add

2010-07-06 00:19:46

by Tilman Schmidt

[permalink] [raw]
Subject: [PATCH 09/11] isdn/gigaset: fix leaks in error path

Take care to free all previously allocated ressources in the
"out of memory" error path of the ISDN_CMD_DIAL branch.
Based on an original patch by Dan Carpenter.

Impact: bugfix
Reported-by: Dan Carpenter <[email protected]>
Signed-off-by: Tilman Schmidt <[email protected]>
Acked-by: Dan Carpenter <[email protected]>
---
drivers/isdn/gigaset/i4l.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/drivers/isdn/gigaset/i4l.c b/drivers/isdn/gigaset/i4l.c
index 1d084bb..34bca37 100644
--- a/drivers/isdn/gigaset/i4l.c
+++ b/drivers/isdn/gigaset/i4l.c
@@ -419,6 +419,8 @@ oom:
dev_err(bcs->cs->dev, "out of memory\n");
for (i = 0; i < AT_NUM; ++i)
kfree(commands[i]);
+ kfree(commands);
+ gigaset_free_channel(bcs);
return -ENOMEM;
}

--
1.6.5.3.298.g39add

2010-07-06 00:19:34

by Tilman Schmidt

[permalink] [raw]
Subject: [PATCH 08/11] isdn/gigaset: reduce syslog spam

Downgrade some error messages which occur frequently during
normal operation to debug messages.

Impact: logging
Signed-off-by: Tilman Schmidt <[email protected]>
---
drivers/isdn/gigaset/capi.c | 16 ++++++++--------
1 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/isdn/gigaset/capi.c b/drivers/isdn/gigaset/capi.c
index 3714aef..b459ed3 100644
--- a/drivers/isdn/gigaset/capi.c
+++ b/drivers/isdn/gigaset/capi.c
@@ -383,13 +383,13 @@ void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *dskb)
++bcs->trans_up;

if (!ap) {
- dev_err(cs->dev, "%s: no application\n", __func__);
+ gig_dbg(DEBUG_MCMD, "%s: application gone", __func__);
return;
}

/* don't send further B3 messages if disconnected */
if (bcs->apconnstate < APCONN_ACTIVE) {
- gig_dbg(DEBUG_MCMD, "disconnected, discarding ack");
+ gig_dbg(DEBUG_MCMD, "%s: disconnected", __func__);
return;
}

@@ -427,13 +427,14 @@ void gigaset_skb_rcvd(struct bc_state *bcs, struct sk_buff *skb)
bcs->trans_down++;

if (!ap) {
- dev_err(cs->dev, "%s: no application\n", __func__);
+ gig_dbg(DEBUG_MCMD, "%s: application gone", __func__);
+ dev_kfree_skb_any(skb);
return;
}

/* don't send further B3 messages if disconnected */
if (bcs->apconnstate < APCONN_ACTIVE) {
- gig_dbg(DEBUG_MCMD, "disconnected, discarding data");
+ gig_dbg(DEBUG_MCMD, "%s: disconnected", __func__);
dev_kfree_skb_any(skb);
return;
}
@@ -752,7 +753,7 @@ void gigaset_isdn_connD(struct bc_state *bcs)
ap = bcs->ap;
if (!ap) {
spin_unlock_irqrestore(&bcs->aplock, flags);
- dev_err(cs->dev, "%s: no application\n", __func__);
+ gig_dbg(DEBUG_CMD, "%s: application gone", __func__);
return;
}
if (bcs->apconnstate == APCONN_NONE) {
@@ -848,7 +849,7 @@ void gigaset_isdn_connB(struct bc_state *bcs)
ap = bcs->ap;
if (!ap) {
spin_unlock_irqrestore(&bcs->aplock, flags);
- dev_err(cs->dev, "%s: no application\n", __func__);
+ gig_dbg(DEBUG_CMD, "%s: application gone", __func__);
return;
}
if (!bcs->apconnstate) {
@@ -906,13 +907,12 @@ void gigaset_isdn_connB(struct bc_state *bcs)
*/
void gigaset_isdn_hupB(struct bc_state *bcs)
{
- struct cardstate *cs = bcs->cs;
struct gigaset_capi_appl *ap = bcs->ap;

/* ToDo: assure order of DISCONNECT_B3_IND and DISCONNECT_IND ? */

if (!ap) {
- dev_err(cs->dev, "%s: no application\n", __func__);
+ gig_dbg(DEBUG_CMD, "%s: application gone", __func__);
return;
}

--
1.6.5.3.298.g39add

2010-07-06 00:19:51

by Tilman Schmidt

[permalink] [raw]
Subject: [PATCH 11/11] isdn/gigaset: remove EXPERIMENTAL tag from GIGASET_CAPI

The CAPI variant of the Gigaset drivers can, in combination with
capidrv, now fully replace the legacy ISDN4Linux variant. All
reported problems have been fixed. So remove the EXPERIMENTAL tag
from the Kconfig option selecting it, and adapt the documentation
accordingly to encourage users to switch to it.

Impact: documentation/status update, no functional change
Signed-off-by: Tilman Schmidt <[email protected]>
---
Documentation/isdn/README.gigaset | 100 +++++++++++++++++++-----------------
drivers/isdn/gigaset/Kconfig | 4 +-
2 files changed, 55 insertions(+), 49 deletions(-)

diff --git a/Documentation/isdn/README.gigaset b/Documentation/isdn/README.gigaset
index e472df8..7502c3f 100644
--- a/Documentation/isdn/README.gigaset
+++ b/Documentation/isdn/README.gigaset
@@ -47,9 +47,9 @@ GigaSet 307x Device Driver

1.2. Software
--------
- The driver works with ISDN4linux and so can be used with any software
- which is able to use ISDN4linux for ISDN connections (voice or data).
- Experimental Kernel CAPI support is available as a compilation option.
+ The driver works with the Kernel CAPI subsystem as well as the old
+ ISDN4Linux subsystem, so it can be used with any software which is able
+ to use CAPI 2.0 or ISDN4Linux for ISDN connections (voice or data).

There are some user space tools available at
http://sourceforge.net/projects/gigaset307x/
@@ -152,61 +152,42 @@ GigaSet 307x Device Driver
- GIGVER_FWBASE: retrieve the firmware version of the base
Upon return, version[] is filled with the requested version information.

-2.3. ISDN4linux
- ----------
- This is the "normal" mode of operation. After loading the module you can
- set up the ISDN system just as you'd do with any ISDN card supported by
- the ISDN4Linux subsystem. Most distributions provide some configuration
- utility. If not, you can use some HOWTOs like
- http://www.linuxhaven.de/dlhp/HOWTO/DE-ISDN-HOWTO-5.html
- If this doesn't work, because you have some device like SX100 where
- debug output (see section 3.2.) shows something like this when dialing
- CMD Received: ERROR
- Available Params: 0
- Connection State: 0, Response: -1
- gigaset_process_response: resp_code -1 in ConState 0 !
- Timeout occurred
- you probably need to use unimodem mode. (see section 2.5.)
-
-2.4. CAPI
+2.3. CAPI
----
If the driver is compiled with CAPI support (kernel configuration option
- GIGASET_CAPI, experimental) it can also be used with CAPI 2.0 kernel and
- user space applications. For user space access, the module capi.ko must
- be loaded. The capiinit command (included in the capi4k-utils package)
- does this for you.
-
- The CAPI variant of the driver supports legacy ISDN4Linux applications
- via the capidrv compatibility driver. The kernel module capidrv.ko must
- be loaded explicitly with the command
+ GIGASET_CAPI) the devices will show up as CAPI controllers as soon as the
+ corresponding driver module is loaded, and can then be used with CAPI 2.0
+ kernel and user space applications. For user space access, the module
+ capi.ko must be loaded.
+
+ Legacy ISDN4Linux applications are supported via the capidrv
+ compatibility driver. The kernel module capidrv.ko must be loaded
+ explicitly with the command
modprobe capidrv
if needed, and cannot be unloaded again without unloading the driver
first. (These are limitations of capidrv.)

- The note about unimodem mode in the preceding section applies here, too.
-
-2.5. Unimodem mode
- -------------
- This is needed for some devices [e.g. SX100] as they have problems with
- the "normal" commands.
+ Most distributions handle loading and unloading of the various CAPI
+ modules automatically via the command capiinit(1) from the capi4k-utils
+ package or a similar mechanism. Note that capiinit(1) cannot unload the
+ Gigaset drivers because it doesn't support more than one module per
+ driver.

- If you have installed the command line tool gigacontr, you can enter
- unimodem mode using
- gigacontr --mode unimodem
- You can switch back using
- gigacontr --mode isdn
+2.4. ISDN4Linux
+ ----------
+ If the driver is compiled without CAPI support (native ISDN4Linux
+ variant), it registers the device with the legacy ISDN4Linux subsystem
+ after loading the module. It can then be used with ISDN4Linux
+ applications only. Most distributions provide some configuration utility
+ for setting up that subsystem. Otherwise you can use some HOWTOs like
+ http://www.linuxhaven.de/dlhp/HOWTO/DE-ISDN-HOWTO-5.html

- You can also put the driver directly into Unimodem mode when it's loaded,
- by passing the module parameter startmode=0 to the hardware specific
- module, e.g.
- modprobe usb_gigaset startmode=0
- or by adding a line like
- options usb_gigaset startmode=0
- to an appropriate module configuration file, like /etc/modprobe.d/gigaset
- or /etc/modprobe.conf.local.

+2.5. Unimodem mode
+ -------------
In this mode the device works like a modem connected to a serial port
(the /dev/ttyGU0, ... mentioned above) which understands the commands
+
ATZ init, reset
=> OK or ERROR
ATD
@@ -234,6 +215,31 @@ GigaSet 307x Device Driver
to an appropriate module configuration file, like /etc/modprobe.d/gigaset
or /etc/modprobe.conf.local.

+ Unimodem mode is needed for making some devices [e.g. SX100] work which
+ do not support the regular Gigaset command set. If debug output (see
+ section 3.2.) shows something like this when dialing:
+ CMD Received: ERROR
+ Available Params: 0
+ Connection State: 0, Response: -1
+ gigaset_process_response: resp_code -1 in ConState 0 !
+ Timeout occurred
+ then switching to unimodem mode may help.
+
+ If you have installed the command line tool gigacontr, you can enter
+ unimodem mode using
+ gigacontr --mode unimodem
+ You can switch back using
+ gigacontr --mode isdn
+
+ You can also put the driver directly into Unimodem mode when it's loaded,
+ by passing the module parameter startmode=0 to the hardware specific
+ module, e.g.
+ modprobe usb_gigaset startmode=0
+ or by adding a line like
+ options usb_gigaset startmode=0
+ to an appropriate module configuration file, like /etc/modprobe.d/gigaset
+ or /etc/modprobe.conf.local.
+
2.6. Call-ID (CID) mode
------------------
Call-IDs are numbers used to tag commands to, and responses from, the
diff --git a/drivers/isdn/gigaset/Kconfig b/drivers/isdn/gigaset/Kconfig
index dcefedc..b18a92c 100644
--- a/drivers/isdn/gigaset/Kconfig
+++ b/drivers/isdn/gigaset/Kconfig
@@ -17,8 +17,7 @@ menuconfig ISDN_DRV_GIGASET
if ISDN_DRV_GIGASET

config GIGASET_CAPI
- bool "Gigaset CAPI support (EXPERIMENTAL)"
- depends on EXPERIMENTAL
+ bool "Gigaset CAPI support"
depends on ISDN_CAPI='y'||(ISDN_CAPI='m'&&ISDN_DRV_GIGASET='m')
default ISDN_I4L='n'
help
@@ -27,6 +26,7 @@ config GIGASET_CAPI
subsystem you'll have to enable the capidrv glue driver.
(select ISDN_CAPI_CAPIDRV.)
Say N to build the old native ISDN4Linux variant.
+ If unsure, say Y.

config GIGASET_I4L
bool
--
1.6.5.3.298.g39add

2010-07-06 00:20:20

by Tilman Schmidt

[permalink] [raw]
Subject: [PATCH 10/11] isdn/gigaset: document dial-out number format

Add a paragraph to the driver documentation describing how to make
internal and external calls.

Impact: documentation
Signed-off-by: Tilman Schmidt <[email protected]>
---
Documentation/isdn/README.gigaset | 17 ++++++++++++++++-
1 files changed, 16 insertions(+), 1 deletions(-)

diff --git a/Documentation/isdn/README.gigaset b/Documentation/isdn/README.gigaset
index e472df8..702c046 100644
--- a/Documentation/isdn/README.gigaset
+++ b/Documentation/isdn/README.gigaset
@@ -263,7 +263,22 @@ GigaSet 307x Device Driver
change its CID mode while the driver is loaded, eg.
echo 0 > /sys/class/tty/ttyGU0/cidmode

-2.7. Unregistered Wireless Devices (M101/M105)
+2.7. Dialing Numbers
+ ---------------
+ The called party number provided by an application for dialing out must
+ be a public network number according to the local dialing plan, without
+ any dial prefix for getting an outside line.
+
+ Internal calls can be made by providing an internal extension number
+ prefixed with "**" (two asterisks) as the called party number. So to dial
+ eg. the first registered DECT handset, give "**11" as the called party
+ number. Dialing "***" (three asterisks) calls all extensions
+ simultaneously (global call).
+
+ This holds for both CAPI 2.0 and ISDN4Linux applications. Unimodem mode
+ does not support internal calls.
+
+2.8. Unregistered Wireless Devices (M101/M105)
-----------------------------------------
The main purpose of the ser_gigaset and usb_gigaset drivers is to allow
the M101 and M105 wireless devices to be used as ISDN devices for ISDN
--
1.6.5.3.298.g39add

2010-07-06 00:19:06

by Tilman Schmidt

[permalink] [raw]
Subject: [PATCH 02/11] isdn/gigaset: avoid copying AT commands twice

Change the Gigaset driver's internal write_cmd interface to accept a
cmdbuf structure instead of a string. This avoids copying formatted
AT commands a second time.

Impact: optimization
Signed-off-by: Tilman Schmidt <[email protected]>
---
drivers/isdn/gigaset/bas-gigaset.c | 51 +++++-------------------
drivers/isdn/gigaset/ev-layer.c | 75 ++++++++++++++++-------------------
drivers/isdn/gigaset/gigaset.h | 4 +-
drivers/isdn/gigaset/interface.c | 36 ++++++++++++++---
drivers/isdn/gigaset/ser-gigaset.c | 27 ++----------
drivers/isdn/gigaset/usb-gigaset.c | 26 ++----------
6 files changed, 85 insertions(+), 134 deletions(-)

diff --git a/drivers/isdn/gigaset/bas-gigaset.c b/drivers/isdn/gigaset/bas-gigaset.c
index 47a5ffe..2dab531 100644
--- a/drivers/isdn/gigaset/bas-gigaset.c
+++ b/drivers/isdn/gigaset/bas-gigaset.c
@@ -1913,65 +1913,41 @@ static int start_cbsend(struct cardstate *cs)
* USB transmission is started if necessary.
* parameters:
* cs controller state structure
- * buf command string to send
- * len number of bytes to send (max. IF_WRITEBUF)
- * wake_tasklet tasklet to run when transmission is completed
- * (NULL if none)
+ * cb command buffer structure
* return value:
* number of bytes queued on success
* error code < 0 on error
*/
-static int gigaset_write_cmd(struct cardstate *cs,
- const unsigned char *buf, int len,
- struct tasklet_struct *wake_tasklet)
+static int gigaset_write_cmd(struct cardstate *cs, struct cmdbuf_t *cb)
{
- struct cmdbuf_t *cb;
unsigned long flags;
int rc;

gigaset_dbg_buffer(cs->mstate != MS_LOCKED ?
DEBUG_TRANSCMD : DEBUG_LOCKCMD,
- "CMD Transmit", len, buf);
-
- if (len <= 0) {
- /* nothing to do */
- rc = 0;
- goto notqueued;
- }
+ "CMD Transmit", cb->len, cb->buf);

/* translate "+++" escape sequence sent as a single separate command
* into "close AT channel" command for error recovery
* The next command will reopen the AT channel automatically.
*/
- if (len == 3 && !memcmp(buf, "+++", 3)) {
+ if (cb->len == 3 && !memcmp(cb->buf, "+++", 3)) {
+ kfree(cb);
rc = req_submit(cs->bcs, HD_CLOSE_ATCHANNEL, 0, BAS_TIMEOUT);
- goto notqueued;
- }
-
- if (len > IF_WRITEBUF)
- len = IF_WRITEBUF;
- cb = kmalloc(sizeof(struct cmdbuf_t) + len, GFP_ATOMIC);
- if (!cb) {
- dev_err(cs->dev, "%s: out of memory\n", __func__);
- rc = -ENOMEM;
- goto notqueued;
+ if (cb->wake_tasklet)
+ tasklet_schedule(cb->wake_tasklet);
+ return rc < 0 ? rc : cb->len;
}

- memcpy(cb->buf, buf, len);
- cb->len = len;
- cb->offset = 0;
- cb->next = NULL;
- cb->wake_tasklet = wake_tasklet;
-
spin_lock_irqsave(&cs->cmdlock, flags);
cb->prev = cs->lastcmdbuf;
if (cs->lastcmdbuf)
cs->lastcmdbuf->next = cb;
else {
cs->cmdbuf = cb;
- cs->curlen = len;
+ cs->curlen = cb->len;
}
- cs->cmdbytes += len;
+ cs->cmdbytes += cb->len;
cs->lastcmdbuf = cb;
spin_unlock_irqrestore(&cs->cmdlock, flags);

@@ -1988,12 +1964,7 @@ static int gigaset_write_cmd(struct cardstate *cs,
}
rc = start_cbsend(cs);
spin_unlock_irqrestore(&cs->lock, flags);
- return rc < 0 ? rc : len;
-
-notqueued: /* request handled without queuing */
- if (wake_tasklet)
- tasklet_schedule(wake_tasklet);
- return rc;
+ return rc < 0 ? rc : cb->len;
}

/* gigaset_write_room
diff --git a/drivers/isdn/gigaset/ev-layer.c b/drivers/isdn/gigaset/ev-layer.c
index ceaef9a..0d5984a 100644
--- a/drivers/isdn/gigaset/ev-layer.c
+++ b/drivers/isdn/gigaset/ev-layer.c
@@ -797,48 +797,27 @@ static void schedule_init(struct cardstate *cs, int state)
static void send_command(struct cardstate *cs, const char *cmd, int cid,
int dle, gfp_t kmallocflags)
{
- size_t cmdlen, buflen;
- char *cmdpos, *cmdbuf, *cmdtail;
+ struct cmdbuf_t *cb;
+ size_t buflen;

- cmdlen = strlen(cmd);
- buflen = 11 + cmdlen;
- if (unlikely(buflen <= cmdlen)) {
- dev_err(cs->dev, "integer overflow in buflen\n");
+ buflen = strlen(cmd) + 12; /* DLE ( A T 1 2 3 4 5 <cmd> DLE ) \0 */
+ cb = kmalloc(sizeof(struct cmdbuf_t) + buflen, kmallocflags);
+ if (!cb) {
+ dev_err(cs->dev, "%s: out of memory\n", __func__);
return;
}
-
- cmdbuf = kmalloc(buflen, kmallocflags);
- if (unlikely(!cmdbuf)) {
- dev_err(cs->dev, "out of memory\n");
- return;
- }
-
- cmdpos = cmdbuf + 9;
- cmdtail = cmdpos + cmdlen;
- memcpy(cmdpos, cmd, cmdlen);
-
- if (cid > 0 && cid <= 65535) {
- do {
- *--cmdpos = '0' + cid % 10;
- cid /= 10;
- ++cmdlen;
- } while (cid);
- }
-
- cmdlen += 2;
- *--cmdpos = 'T';
- *--cmdpos = 'A';
-
- if (dle) {
- cmdlen += 4;
- *--cmdpos = '(';
- *--cmdpos = 0x10;
- *cmdtail++ = 0x10;
- *cmdtail++ = ')';
- }
-
- cs->ops->write_cmd(cs, cmdpos, cmdlen, NULL);
- kfree(cmdbuf);
+ if (cid > 0 && cid <= 65535)
+ cb->len = snprintf(cb->buf, buflen,
+ dle ? "\020(AT%d%s\020)" : "AT%d%s",
+ cid, cmd);
+ else
+ cb->len = snprintf(cb->buf, buflen,
+ dle ? "\020(AT%s\020)" : "AT%s",
+ cmd);
+ cb->offset = 0;
+ cb->next = NULL;
+ cb->wake_tasklet = NULL;
+ cs->ops->write_cmd(cs, cb);
}

static struct at_state_t *at_state_from_cid(struct cardstate *cs, int cid)
@@ -1240,8 +1219,22 @@ static void do_action(int action, struct cardstate *cs,
break;
case ACT_HUPMODEM:
/* send "+++" (hangup in unimodem mode) */
- if (cs->connected)
- cs->ops->write_cmd(cs, "+++", 3, NULL);
+ if (cs->connected) {
+ struct cmdbuf_t *cb;
+
+ cb = kmalloc(sizeof(struct cmdbuf_t) + 3, GFP_ATOMIC);
+ if (!cb) {
+ dev_err(cs->dev, "%s: out of memory\n",
+ __func__);
+ return;
+ }
+ memcpy(cb->buf, "+++", 3);
+ cb->len = 3;
+ cb->offset = 0;
+ cb->next = NULL;
+ cb->wake_tasklet = NULL;
+ cs->ops->write_cmd(cs, cb);
+ }
break;
case ACT_RING:
/* get fresh AT state structure for new CID */
diff --git a/drivers/isdn/gigaset/gigaset.h b/drivers/isdn/gigaset/gigaset.h
index 8738b08..904c947 100644
--- a/drivers/isdn/gigaset/gigaset.h
+++ b/drivers/isdn/gigaset/gigaset.h
@@ -574,9 +574,7 @@ struct bas_bc_state {
struct gigaset_ops {
/* Called from ev-layer.c/interface.c for sending AT commands to the
device */
- int (*write_cmd)(struct cardstate *cs,
- const unsigned char *buf, int len,
- struct tasklet_struct *wake_tasklet);
+ int (*write_cmd)(struct cardstate *cs, struct cmdbuf_t *cb);

/* Called from interface.c for additional device control */
int (*write_room)(struct cardstate *cs);
diff --git a/drivers/isdn/gigaset/interface.c b/drivers/isdn/gigaset/interface.c
index c9f28dd..f45d686 100644
--- a/drivers/isdn/gigaset/interface.c
+++ b/drivers/isdn/gigaset/interface.c
@@ -339,7 +339,8 @@ static int if_tiocmset(struct tty_struct *tty, struct file *file,
static int if_write(struct tty_struct *tty, const unsigned char *buf, int count)
{
struct cardstate *cs;
- int retval = -ENODEV;
+ struct cmdbuf_t *cb;
+ int retval;

cs = (struct cardstate *) tty->driver_data;
if (!cs) {
@@ -355,18 +356,39 @@ static int if_write(struct tty_struct *tty, const unsigned char *buf, int count)
if (!cs->connected) {
gig_dbg(DEBUG_IF, "not connected");
retval = -ENODEV;
- } else if (!cs->open_count)
+ goto done;
+ }
+ if (!cs->open_count) {
dev_warn(cs->dev, "%s: device not opened\n", __func__);
- else if (cs->mstate != MS_LOCKED) {
+ retval = -ENODEV;
+ goto done;
+ }
+ if (cs->mstate != MS_LOCKED) {
dev_warn(cs->dev, "can't write to unlocked device\n");
retval = -EBUSY;
- } else {
- retval = cs->ops->write_cmd(cs, buf, count,
- &cs->if_wake_tasklet);
+ goto done;
+ }
+ if (count <= 0) {
+ /* nothing to do */
+ retval = 0;
+ goto done;
}

- mutex_unlock(&cs->mutex);
+ cb = kmalloc(sizeof(struct cmdbuf_t) + count, GFP_KERNEL);
+ if (!cb) {
+ dev_err(cs->dev, "%s: out of memory\n", __func__);
+ retval = -ENOMEM;
+ goto done;
+ }

+ memcpy(cb->buf, buf, count);
+ cb->len = count;
+ cb->offset = 0;
+ cb->next = NULL;
+ cb->wake_tasklet = &cs->if_wake_tasklet;
+ retval = cs->ops->write_cmd(cs, cb);
+done:
+ mutex_unlock(&cs->mutex);
return retval;
}

diff --git a/drivers/isdn/gigaset/ser-gigaset.c b/drivers/isdn/gigaset/ser-gigaset.c
index e96c058..d151dcb 100644
--- a/drivers/isdn/gigaset/ser-gigaset.c
+++ b/drivers/isdn/gigaset/ser-gigaset.c
@@ -241,30 +241,13 @@ static void flush_send_queue(struct cardstate *cs)
* return value:
* number of bytes queued, or error code < 0
*/
-static int gigaset_write_cmd(struct cardstate *cs, const unsigned char *buf,
- int len, struct tasklet_struct *wake_tasklet)
+static int gigaset_write_cmd(struct cardstate *cs, struct cmdbuf_t *cb)
{
- struct cmdbuf_t *cb;
unsigned long flags;

gigaset_dbg_buffer(cs->mstate != MS_LOCKED ?
DEBUG_TRANSCMD : DEBUG_LOCKCMD,
- "CMD Transmit", len, buf);
-
- if (len <= 0)
- return 0;
-
- cb = kmalloc(sizeof(struct cmdbuf_t) + len, GFP_ATOMIC);
- if (!cb) {
- dev_err(cs->dev, "%s: out of memory!\n", __func__);
- return -ENOMEM;
- }
-
- memcpy(cb->buf, buf, len);
- cb->len = len;
- cb->offset = 0;
- cb->next = NULL;
- cb->wake_tasklet = wake_tasklet;
+ "CMD Transmit", cb->len, cb->buf);

spin_lock_irqsave(&cs->cmdlock, flags);
cb->prev = cs->lastcmdbuf;
@@ -272,9 +255,9 @@ static int gigaset_write_cmd(struct cardstate *cs, const unsigned char *buf,
cs->lastcmdbuf->next = cb;
else {
cs->cmdbuf = cb;
- cs->curlen = len;
+ cs->curlen = cb->len;
}
- cs->cmdbytes += len;
+ cs->cmdbytes += cb->len;
cs->lastcmdbuf = cb;
spin_unlock_irqrestore(&cs->cmdlock, flags);

@@ -282,7 +265,7 @@ static int gigaset_write_cmd(struct cardstate *cs, const unsigned char *buf,
if (cs->connected)
tasklet_schedule(&cs->write_tasklet);
spin_unlock_irqrestore(&cs->lock, flags);
- return len;
+ return cb->len;
}

/*
diff --git a/drivers/isdn/gigaset/usb-gigaset.c b/drivers/isdn/gigaset/usb-gigaset.c
index f65cf7d..4a66338 100644
--- a/drivers/isdn/gigaset/usb-gigaset.c
+++ b/drivers/isdn/gigaset/usb-gigaset.c
@@ -494,29 +494,13 @@ static int send_cb(struct cardstate *cs, struct cmdbuf_t *cb)
}

/* Send command to device. */
-static int gigaset_write_cmd(struct cardstate *cs, const unsigned char *buf,
- int len, struct tasklet_struct *wake_tasklet)
+static int gigaset_write_cmd(struct cardstate *cs, struct cmdbuf_t *cb)
{
- struct cmdbuf_t *cb;
unsigned long flags;

gigaset_dbg_buffer(cs->mstate != MS_LOCKED ?
DEBUG_TRANSCMD : DEBUG_LOCKCMD,
- "CMD Transmit", len, buf);
-
- if (len <= 0)
- return 0;
- cb = kmalloc(sizeof(struct cmdbuf_t) + len, GFP_ATOMIC);
- if (!cb) {
- dev_err(cs->dev, "%s: out of memory\n", __func__);
- return -ENOMEM;
- }
-
- memcpy(cb->buf, buf, len);
- cb->len = len;
- cb->offset = 0;
- cb->next = NULL;
- cb->wake_tasklet = wake_tasklet;
+ "CMD Transmit", cb->len, cb->buf);

spin_lock_irqsave(&cs->cmdlock, flags);
cb->prev = cs->lastcmdbuf;
@@ -524,9 +508,9 @@ static int gigaset_write_cmd(struct cardstate *cs, const unsigned char *buf,
cs->lastcmdbuf->next = cb;
else {
cs->cmdbuf = cb;
- cs->curlen = len;
+ cs->curlen = cb->len;
}
- cs->cmdbytes += len;
+ cs->cmdbytes += cb->len;
cs->lastcmdbuf = cb;
spin_unlock_irqrestore(&cs->cmdlock, flags);

@@ -534,7 +518,7 @@ static int gigaset_write_cmd(struct cardstate *cs, const unsigned char *buf,
if (cs->connected)
tasklet_schedule(&cs->write_tasklet);
spin_unlock_irqrestore(&cs->lock, flags);
- return len;
+ return cb->len;
}

static int gigaset_write_room(struct cardstate *cs)
--
1.6.5.3.298.g39add

2010-07-06 01:53:40

by David Miller

[permalink] [raw]
Subject: Re: [PATCH 00/11] ISDN patches for 2.6.36

From: Tilman Schmidt <[email protected]>
Date: Tue, 6 Jul 2010 02:18:32 +0200 (CEST)

> Karsten, David,
>
> following are a series of patches to the Gigaset driver I'd like
> to see included in kernel release 2.6.36.

Do they have any dependencies on the two patch set of fixes
you just sent out for net-2.6?

You must always let me know this so I don't go blindly trying
to apply your patches onto to find that they don't apply cleanly
because of a dependency you have failed to mention.

2010-07-06 01:54:54

by David Miller

[permalink] [raw]
Subject: Re: [PATCH 00/11] ISDN patches for 2.6.36

From: David Miller <[email protected]>
Date: Mon, 05 Jul 2010 18:53:52 -0700 (PDT)

> From: Tilman Schmidt <[email protected]>
> Date: Tue, 6 Jul 2010 02:18:32 +0200 (CEST)
>
>> Karsten, David,
>>
>> following are a series of patches to the Gigaset driver I'd like
>> to see included in kernel release 2.6.36.
>
> Do they have any dependencies on the two patch set of fixes
> you just sent out for net-2.6?
^^^^^^^

Of course I meant net-next-2.6

> You must always let me know this so I don't go blindly trying
> to apply your patches onto to find that they don't apply cleanly
> because of a dependency you have failed to mention.
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/

2010-07-06 02:23:43

by David Miller

[permalink] [raw]
Subject: Re: [PATCH 05/11] isdn/gigaset: improve CAPI message debugging

From: Tilman Schmidt <[email protected]>
Date: Tue, 6 Jul 2010 02:18:59 +0200 (CEST)

> @@ -384,7 +388,7 @@ void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *dskb)
>
> /* don't send further B3 messages if disconnected */
> if (bcs->apconnstate < APCONN_ACTIVE) {
> - gig_dbg(DEBUG_LLDATA, "disconnected, discarding ack");
> + gig_dbg(DEBUG_MCMD, "disconnected, discarding ack");
> return;
> }

This is against something other than net-next-2.6 even with your
other two ISDN patches applied, because all of these lines read
"if (ap->connected ..."

Please tell me what exactly these patches are against so that I
can apply them to net-next-2.6 cleanly.

2010-07-06 07:47:53

by Tilman Schmidt

[permalink] [raw]
Subject: Re: [PATCH 00/11] ISDN patches for 2.6.36

Am 2010-07-06 03:53 schrieb David Miller:
> From: Tilman Schmidt <[email protected]>
> Date: Tue, 6 Jul 2010 02:18:32 +0200 (CEST)
>
>> Karsten, David,
>>
>> following are a series of patches to the Gigaset driver I'd like
>> to see included in kernel release 2.6.36.
>
> Do they have any dependencies on the two patch set of fixes
> you just sent out for net-2.6?

None. They are completely independent.

I guess your question arose because I gave both series the same
title by mistake. The second one should have been called:
"*Gigaset* patches for 2.6.36".

Thanks,
Tilman


Attachments:
signature.asc (260.00 B)
OpenPGP digital signature

2010-07-06 08:15:09

by Tilman Schmidt

[permalink] [raw]
Subject: Re: [PATCH 05/11] isdn/gigaset: improve CAPI message debugging

Am 2010-07-06 04:23 schrieb David Miller:
> From: Tilman Schmidt <[email protected]>
> Date: Tue, 6 Jul 2010 02:18:59 +0200 (CEST)
>
>> @@ -384,7 +388,7 @@ void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *dskb)
>>
>> /* don't send further B3 messages if disconnected */
>> if (bcs->apconnstate < APCONN_ACTIVE) {
>> - gig_dbg(DEBUG_LLDATA, "disconnected, discarding ack");
>> + gig_dbg(DEBUG_MCMD, "disconnected, discarding ack");
>> return;
>> }
>
> This is against something other than net-next-2.6 even with your
> other two ISDN patches applied, because all of these lines read
> "if (ap->connected ..."
>
> Please tell me what exactly these patches are against so that I
> can apply them to net-next-2.6 cleanly.

They are against mainline and apply cleanly to v2.6.35-rc3.
IOW, they go on top of the series you applied to net-2.6 on
Fri, 25 Jun 2010 21:31:28 -0700 (PDT).

Specifically, the last patch of that series,
> Subject: [PATCH 5/5] isdn/gigaset: correct CAPI connection state storage
makes the switch from ap->connected to bcs->apconnstate.

So if you'll postpone applying last night's series until
after your next merge of net-2.6 into net-next-2.6, it
should then apply cleanly.

Thanks,
Tilman


Attachments:
signature.asc (260.00 B)
OpenPGP digital signature

2010-07-06 17:43:59

by David Miller

[permalink] [raw]
Subject: Re: [PATCH 05/11] isdn/gigaset: improve CAPI message debugging

From: Tilman Schmidt <[email protected]>
Date: Tue, 06 Jul 2010 10:14:53 +0200

> So if you'll postpone applying last night's series until
> after your next merge of net-2.6 into net-next-2.6, it
> should then apply cleanly.

That's the kind of information I'd like to see from you when you
post patches which have such dependencies.

Thanks.

2010-07-06 20:32:16

by Tilman Schmidt

[permalink] [raw]
Subject: Re: [PATCH 05/11] isdn/gigaset: improve CAPI message debugging

Am 06.07.2010 19:44 schrieb David Miller:
> From: Tilman Schmidt <[email protected]>
> Date: Tue, 06 Jul 2010 10:14:53 +0200
>
>> So if you'll postpone applying last night's series until
>> after your next merge of net-2.6 into net-next-2.6, it
>> should then apply cleanly.
>
> That's the kind of information I'd like to see from you when you
> post patches which have such dependencies.

Understood. It's just that I had thought my "for 2.6.35" patches
had already been applied to net-next-2.6, anyway. When I got
your complaint I noticed I had been mistaken. Sorry for that.
I know how that mistake arose, and it won't happen again.

Thanks,
Tilman

--
Tilman Schmidt E-Mail: [email protected]
Bonn, Germany
Diese Nachricht besteht zu 100% aus wiederverwerteten Bits.
Unge?ffnet mindestens haltbar bis: (siehe R?ckseite)


Attachments:
signature.asc (259.00 B)
OpenPGP digital signature