* [PATCH 05/12] gigaset: announce if built with debugging
From: Tilman Schmidt @ 2009-09-18 23:57 UTC (permalink / raw)
To: Karsten Keil, Karsten Keil
Cc: Hansjoerg Lipp, davem, i4ldeveloper, netdev, linux-kernel
In-Reply-To: <20090919-patch-gigaset-00.tilman@imap.cc>
Mention in the driver load announcement whether the driver was built
with debugging messages enabled, to facilitate support.
Impact: informational message
Signed-off-by: Tilman Schmidt <tilman@imap.cc>
---
drivers/isdn/gigaset/common.c | 8 +++++++-
1 files changed, 7 insertions(+), 1 deletions(-)
diff --git a/drivers/isdn/gigaset/common.c b/drivers/isdn/gigaset/common.c
index e4141bf..edbcaa3 100644
--- a/drivers/isdn/gigaset/common.c
+++ b/drivers/isdn/gigaset/common.c
@@ -22,6 +22,12 @@
#define DRIVER_AUTHOR "Hansjoerg Lipp <hjlipp@web.de>, Tilman Schmidt <tilman@imap.cc>, Stefan Eilers"
#define DRIVER_DESC "Driver for Gigaset 307x"
+#ifdef CONFIG_GIGASET_DEBUG
+#define DRIVER_DESC_DEBUG " (debug build)"
+#else
+#define DRIVER_DESC_DEBUG ""
+#endif
+
/* Module parameters */
int gigaset_debuglevel = DEBUG_DEFAULT;
EXPORT_SYMBOL_GPL(gigaset_debuglevel);
@@ -1110,7 +1116,7 @@ static int __init gigaset_init_module(void)
if (gigaset_debuglevel == 1)
gigaset_debuglevel = DEBUG_DEFAULT;
- pr_info(DRIVER_DESC "\n");
+ pr_info(DRIVER_DESC DRIVER_DESC_DEBUG "\n");
return 0;
}
--
1.6.2.1.214.ge986c
^ permalink raw reply related
* [PATCH 07/12] gigaset: improve error recovery (v2)
From: Tilman Schmidt @ 2009-09-18 23:57 UTC (permalink / raw)
To: Karsten Keil, Karsten Keil
Cc: Hansjoerg Lipp, davem, i4ldeveloper, netdev, linux-kernel
In-Reply-To: <20090919-patch-gigaset-00.tilman@imap.cc>
When the Gigaset base stops responding, try resetting the USB
connection to recover.
Impact: error handling improvement
Signed-off-by: Tilman Schmidt <tilman@imap.cc>
---
drivers/isdn/gigaset/bas-gigaset.c | 69 +++++++++++++++++++++++------------
1 files changed, 45 insertions(+), 24 deletions(-)
diff --git a/drivers/isdn/gigaset/bas-gigaset.c b/drivers/isdn/gigaset/bas-gigaset.c
index 9e7108a..5ed1d99 100644
--- a/drivers/isdn/gigaset/bas-gigaset.c
+++ b/drivers/isdn/gigaset/bas-gigaset.c
@@ -134,6 +134,7 @@ struct bas_cardstate {
#define BS_ATRDPEND 0x040 /* urb_cmd_in in use */
#define BS_ATWRPEND 0x080 /* urb_cmd_out in use */
#define BS_SUSPEND 0x100 /* USB port suspended */
+#define BS_RESETTING 0x200 /* waiting for HD_RESET_INTERRUPT_PIPE_ACK */
static struct gigaset_driver *driver = NULL;
@@ -319,6 +320,21 @@ static int gigaset_set_line_ctrl(struct cardstate *cs, unsigned cflag)
return -EINVAL;
}
+/* set/clear bits in base connection state, return previous state
+ */
+static inline int update_basstate(struct bas_cardstate *ucs,
+ int set, int clear)
+{
+ unsigned long flags;
+ int state;
+
+ spin_lock_irqsave(&ucs->lock, flags);
+ state = ucs->basstate;
+ ucs->basstate = (state & ~clear) | set;
+ spin_unlock_irqrestore(&ucs->lock, flags);
+ return state;
+}
+
/* error_hangup
* hang up any existing connection because of an unrecoverable error
* This function may be called from any context and takes care of scheduling
@@ -350,12 +366,9 @@ static inline void error_hangup(struct bc_state *bcs)
*/
static inline void error_reset(struct cardstate *cs)
{
- /* close AT command channel to recover (ignore errors) */
- req_submit(cs->bcs, HD_CLOSE_ATCHANNEL, 0, BAS_TIMEOUT);
-
- //FIXME try to recover without bothering the user
- dev_err(cs->dev,
- "unrecoverable error - please disconnect Gigaset base to reset\n");
+ /* reset interrupt pipe to recover (ignore errors) */
+ update_basstate(cs->hw.bas, BS_RESETTING, 0);
+ req_submit(cs->bcs, HD_RESET_INTERRUPT_PIPE, 0, BAS_TIMEOUT);
}
/* check_pending
@@ -398,8 +411,13 @@ static void check_pending(struct bas_cardstate *ucs)
case HD_DEVICE_INIT_ACK: /* no reply expected */
ucs->pending = 0;
break;
- /* HD_READ_ATMESSAGE, HD_WRITE_ATMESSAGE, HD_RESET_INTERRUPTPIPE
- * are handled separately and should never end up here
+ case HD_RESET_INTERRUPT_PIPE:
+ if (!(ucs->basstate & BS_RESETTING))
+ ucs->pending = 0;
+ break;
+ /*
+ * HD_READ_ATMESSAGE and HD_WRITE_ATMESSAGE are handled separately
+ * and should never end up here
*/
default:
dev_warn(&ucs->interface->dev,
@@ -449,21 +467,6 @@ static void cmd_in_timeout(unsigned long data)
error_reset(cs);
}
-/* set/clear bits in base connection state, return previous state
- */
-inline static int update_basstate(struct bas_cardstate *ucs,
- int set, int clear)
-{
- unsigned long flags;
- int state;
-
- spin_lock_irqsave(&ucs->lock, flags);
- state = ucs->basstate;
- ucs->basstate = (state & ~clear) | set;
- spin_unlock_irqrestore(&ucs->lock, flags);
- return state;
-}
-
/* read_ctrl_callback
* USB completion handler for control pipe input
* called by the USB subsystem in interrupt context
@@ -762,7 +765,8 @@ static void read_int_callback(struct urb *urb)
break;
case HD_RESET_INTERRUPT_PIPE_ACK:
- gig_dbg(DEBUG_USBREQ, "HD_RESET_INTERRUPT_PIPE_ACK");
+ update_basstate(ucs, 0, BS_RESETTING);
+ dev_notice(cs->dev, "interrupt pipe reset\n");
break;
case HD_SUSPEND_END:
@@ -1429,6 +1433,7 @@ static void req_timeout(unsigned long data)
case HD_CLOSE_ATCHANNEL:
dev_err(bcs->cs->dev, "timeout closing AT channel\n");
+ error_reset(bcs->cs);
break;
case HD_CLOSE_B2CHANNEL:
@@ -1438,6 +1443,13 @@ static void req_timeout(unsigned long data)
error_reset(bcs->cs);
break;
+ case HD_RESET_INTERRUPT_PIPE:
+ /* error recovery escalation */
+ dev_err(bcs->cs->dev,
+ "reset interrupt pipe timeout, attempting USB reset\n");
+ usb_queue_reset_device(bcs->cs->hw.bas->interface);
+ break;
+
default:
dev_warn(bcs->cs->dev, "request 0x%02x timed out, clearing\n",
pending);
@@ -1930,6 +1942,15 @@ static int gigaset_write_cmd(struct cardstate *cs,
goto notqueued;
}
+ /* 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)) {
+ rc = req_submit(cs->bcs, HD_CLOSE_ATCHANNEL, 0, BAS_TIMEOUT);
+ goto notqueued;
+ }
+
if (len > IF_WRITEBUF)
len = IF_WRITEBUF;
if (!(cb = kmalloc(sizeof(struct cmdbuf_t) + len, GFP_ATOMIC))) {
--
1.6.2.1.214.ge986c
^ permalink raw reply related
* [PATCH 02/12] gigaset: fix reject/hangup handling
From: Tilman Schmidt @ 2009-09-18 23:57 UTC (permalink / raw)
To: Karsten Keil, Karsten Keil
Cc: Hansjoerg Lipp, davem, i4ldeveloper, netdev, linux-kernel
In-Reply-To: <20090919-patch-gigaset-00.tilman@imap.cc>
Signal D channel disconnect in a few cases where it was missed,
including when an incoming call is disconnected before it was
accepted.
Impact: error handling improvement
Signed-off-by: Tilman Schmidt <tilman@imap.cc>
---
drivers/isdn/gigaset/ev-layer.c | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/drivers/isdn/gigaset/ev-layer.c b/drivers/isdn/gigaset/ev-layer.c
index 2d91049..ff2ec2c 100644
--- a/drivers/isdn/gigaset/ev-layer.c
+++ b/drivers/isdn/gigaset/ev-layer.c
@@ -707,6 +707,11 @@ static void disconnect(struct at_state_t **at_state_p)
if (bcs) {
/* B channel assigned: invoke hardware specific handler */
cs->ops->close_bchannel(bcs);
+ /* notify LL */
+ if (bcs->chstate & (CHS_D_UP | CHS_NOTIFY_LL)) {
+ bcs->chstate &= ~(CHS_D_UP | CHS_NOTIFY_LL);
+ gigaset_i4l_channel_cmd(bcs, ISDN_STAT_DHUP);
+ }
} else {
/* no B channel assigned: just deallocate */
spin_lock_irqsave(&cs->lock, flags);
--
1.6.2.1.214.ge986c
^ permalink raw reply related
* [PATCH 04/12] gigaset: handle isoc frame errors more gracefully
From: Tilman Schmidt @ 2009-09-18 23:57 UTC (permalink / raw)
To: Karsten Keil, Karsten Keil
Cc: Hansjoerg Lipp, davem, i4ldeveloper, netdev, linux-kernel
In-Reply-To: <20090919-patch-gigaset-00.tilman@imap.cc>
Don't drop the remainder of an URB if an isochronous frame has an error.
Impact: error handling improvement
Signed-off-by: Tilman Schmidt <tilman@imap.cc>
---
drivers/isdn/gigaset/bas-gigaset.c | 18 +++++++-----------
1 files changed, 7 insertions(+), 11 deletions(-)
diff --git a/drivers/isdn/gigaset/bas-gigaset.c b/drivers/isdn/gigaset/bas-gigaset.c
index 781c404..9e7108a 100644
--- a/drivers/isdn/gigaset/bas-gigaset.c
+++ b/drivers/isdn/gigaset/bas-gigaset.c
@@ -1331,28 +1331,24 @@ static void read_iso_tasklet(unsigned long data)
rcvbuf = urb->transfer_buffer;
totleft = urb->actual_length;
for (frame = 0; totleft > 0 && frame < BAS_NUMFRAMES; frame++) {
- if (unlikely(urb->iso_frame_desc[frame].status)) {
+ numbytes = urb->iso_frame_desc[frame].actual_length;
+ if (unlikely(urb->iso_frame_desc[frame].status))
dev_warn(cs->dev,
- "isochronous read: frame %d: %s\n",
- frame,
+ "isochronous read: frame %d[%d]: %s\n",
+ frame, numbytes,
get_usb_statmsg(
urb->iso_frame_desc[frame].status));
- break;
- }
- numbytes = urb->iso_frame_desc[frame].actual_length;
- if (unlikely(numbytes > BAS_MAXFRAME)) {
+ if (unlikely(numbytes > BAS_MAXFRAME))
dev_warn(cs->dev,
"isochronous read: frame %d: "
"numbytes (%d) > BAS_MAXFRAME\n",
frame, numbytes);
- break;
- }
if (unlikely(numbytes > totleft)) {
dev_warn(cs->dev,
"isochronous read: frame %d: "
"numbytes (%d) > totleft (%d)\n",
frame, numbytes, totleft);
- break;
+ numbytes = totleft;
}
offset = urb->iso_frame_desc[frame].offset;
if (unlikely(offset + numbytes > BAS_INBUFSIZE)) {
@@ -1361,7 +1357,7 @@ static void read_iso_tasklet(unsigned long data)
"offset (%d) + numbytes (%d) "
"> BAS_INBUFSIZE\n",
frame, offset, numbytes);
- break;
+ numbytes = BAS_INBUFSIZE - offset;
}
gigaset_isoc_receive(rcvbuf + offset, numbytes, bcs);
totleft -= numbytes;
--
1.6.2.1.214.ge986c
^ permalink raw reply related
* [PATCH 11/12] gigaset: allow building without I4L
From: Tilman Schmidt @ 2009-09-18 23:57 UTC (permalink / raw)
To: Karsten Keil, Karsten Keil
Cc: Hansjoerg Lipp, davem, i4ldeveloper, netdev, linux-kernel
In-Reply-To: <20090919-patch-gigaset-00.tilman@imap.cc>
Add a dummy LL interface to the Gigaset driver so that it can be
built and, in a limited way, used without the ISDN4Linux subsystem.
Impact: new configuration alternative
Signed-off-by: Tilman Schmidt <tilman@imap.cc>
---
drivers/isdn/gigaset/Kconfig | 13 +++++++-
drivers/isdn/gigaset/Makefile | 4 ++-
drivers/isdn/gigaset/dummyll.c | 68 ++++++++++++++++++++++++++++++++++++++++
3 files changed, 83 insertions(+), 2 deletions(-)
create mode 100644 drivers/isdn/gigaset/dummyll.c
diff --git a/drivers/isdn/gigaset/Kconfig b/drivers/isdn/gigaset/Kconfig
index 18ab865..6fd2dc1 100644
--- a/drivers/isdn/gigaset/Kconfig
+++ b/drivers/isdn/gigaset/Kconfig
@@ -1,6 +1,5 @@
menuconfig ISDN_DRV_GIGASET
tristate "Siemens Gigaset support"
- depends on ISDN_I4L
select CRC_CCITT
select BITREVERSE
help
@@ -11,9 +10,21 @@ menuconfig ISDN_DRV_GIGASET
If you have one of these devices, say M here and for at least
one of the connection specific parts that follow.
This will build a module called "gigaset".
+ Note: If you build the ISDN4Linux subsystem (ISDN_I4L)
+ as a module, you have to build this driver as a module too,
+ otherwise the Gigaset device won't show up as an ISDN device.
if ISDN_DRV_GIGASET
+config GIGASET_I4L
+ bool
+ depends on ISDN_I4L='y'||(ISDN_I4L='m'&&ISDN_DRV_GIGASET='m')
+ default y
+
+config GIGASET_DUMMYLL
+ bool
+ default !GIGASET_I4L
+
config GIGASET_BASE
tristate "Gigaset base station support"
depends on USB
diff --git a/drivers/isdn/gigaset/Makefile b/drivers/isdn/gigaset/Makefile
index e9d3189..d429202 100644
--- a/drivers/isdn/gigaset/Makefile
+++ b/drivers/isdn/gigaset/Makefile
@@ -1,4 +1,6 @@
-gigaset-y := common.o interface.o proc.o ev-layer.o i4l.o asyncdata.o
+gigaset-y := common.o interface.o proc.o ev-layer.o asyncdata.o
+gigaset-$(CONFIG_GIGASET_I4L) += i4l.o
+gigaset-$(CONFIG_GIGASET_DUMMYLL) += dummyll.o
usb_gigaset-y := usb-gigaset.o
ser_gigaset-y := ser-gigaset.o
bas_gigaset-y := bas-gigaset.o isocdata.o
diff --git a/drivers/isdn/gigaset/dummyll.c b/drivers/isdn/gigaset/dummyll.c
new file mode 100644
index 0000000..5b27c99
--- /dev/null
+++ b/drivers/isdn/gigaset/dummyll.c
@@ -0,0 +1,68 @@
+/*
+ * Dummy LL interface for the Gigaset driver
+ *
+ * Copyright (c) 2009 by Tilman Schmidt <tilman@imap.cc>.
+ *
+ * =====================================================================
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ * =====================================================================
+ */
+
+#include "gigaset.h"
+
+void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *skb)
+{
+}
+EXPORT_SYMBOL_GPL(gigaset_skb_sent);
+
+void gigaset_skb_rcvd(struct bc_state *bcs, struct sk_buff *skb)
+{
+}
+EXPORT_SYMBOL_GPL(gigaset_skb_rcvd);
+
+void gigaset_isdn_rcv_err(struct bc_state *bcs)
+{
+}
+EXPORT_SYMBOL_GPL(gigaset_isdn_rcv_err);
+
+int gigaset_isdn_icall(struct at_state_t *at_state)
+{
+ return ICALL_IGNORE;
+}
+
+void gigaset_isdn_connD(struct bc_state *bcs)
+{
+}
+
+void gigaset_isdn_hupD(struct bc_state *bcs)
+{
+}
+
+void gigaset_isdn_connB(struct bc_state *bcs)
+{
+}
+
+void gigaset_isdn_hupB(struct bc_state *bcs)
+{
+}
+
+void gigaset_isdn_start(struct cardstate *cs)
+{
+}
+
+void gigaset_isdn_stop(struct cardstate *cs)
+{
+}
+
+int gigaset_isdn_register(struct cardstate *cs, const char *isdnid)
+{
+ pr_info("no ISDN subsystem interface\n");
+ return 1;
+}
+
+void gigaset_isdn_unregister(struct cardstate *cs)
+{
+}
--
1.6.2.1.214.ge986c
^ permalink raw reply related
* [PATCH 06/12] gigaset: fix device ERROR response handling (v2)
From: Tilman Schmidt @ 2009-09-18 23:57 UTC (permalink / raw)
To: Karsten Keil, Karsten Keil
Cc: Hansjoerg Lipp, davem, i4ldeveloper, netdev, linux-kernel
In-Reply-To: <20090919-patch-gigaset-00.tilman@imap.cc>
Clear out pending command that got rejected with 'ERROR' response.
This fixes the bug where unloading the driver module would hang
with the message: "gigaset: not searching scheduled commands: busy"
Impact: error handling bugfix
Signed-off-by: Tilman Schmidt <tilman@imap.cc>
---
drivers/isdn/gigaset/ev-layer.c | 16 ++++++++--------
1 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/isdn/gigaset/ev-layer.c b/drivers/isdn/gigaset/ev-layer.c
index ff2ec2c..926370a 100644
--- a/drivers/isdn/gigaset/ev-layer.c
+++ b/drivers/isdn/gigaset/ev-layer.c
@@ -207,7 +207,6 @@ struct reply_t gigaset_tab_nocid[] =
/* leave dle mode */
{RSP_INIT, 0, 0,SEQ_DLE0, 201, 5, {0}, "^SDLE=0\r"},
{RSP_OK, 201,201, -1, 202,-1},
- //{RSP_ZDLE, 202,202, 0, 202, 0, {ACT_ERROR}},//DELETE
{RSP_ZDLE, 202,202, 0, 0, 0, {ACT_DLE0}},
{RSP_NODEV, 200,249, -1, 0, 0, {ACT_FAKEDLE0}},
{RSP_ERROR, 200,249, -1, 0, 0, {ACT_FAILDLE0}},
@@ -265,6 +264,7 @@ struct reply_t gigaset_tab_nocid[] =
{EV_SHUTDOWN, -1, -1, -1, -1,-1, {ACT_SHUTDOWN}}, //FIXME
/* misc. */
+ {RSP_ERROR, -1, -1, -1, -1, -1, {ACT_ERROR} },
{RSP_EMPTY, -1, -1, -1, -1,-1, {ACT_DEBUG}}, //FIXME
{RSP_ZCFGT, -1, -1, -1, -1,-1, {ACT_DEBUG}}, //FIXME
{RSP_ZCFG, -1, -1, -1, -1,-1, {ACT_DEBUG}}, //FIXME
@@ -328,10 +328,9 @@ struct reply_t gigaset_tab_cid[] =
{RSP_INIT, -1, -1,SEQ_HUP, 401, 5, {0}, "+VLS=0\r"}, /* hang up */ //-1,-1?
{RSP_OK, 401,401, -1, 402, 5},
{RSP_ZVLS, 402,402, 0, 403, 5},
- {RSP_ZSAU, 403,403,ZSAU_DISCONNECT_REQ, -1,-1, {ACT_DEBUG}}, /* if not remote hup */
- //{RSP_ZSAU, 403,403,ZSAU_NULL, 401, 0, {ACT_ERROR}}, //DELETE//FIXME -> DLE0 // should we do this _before_ hanging up for base driver?
- {RSP_ZSAU, 403,403,ZSAU_NULL, 0, 0, {ACT_DISCONNECT}}, //FIXME -> DLE0 // should we do this _before_ hanging up for base driver?
- {RSP_NODEV, 401,403, -1, 0, 0, {ACT_FAKEHUP}}, //FIXME -> DLE0 // should we do this _before_ hanging up for base driver?
+ {RSP_ZSAU, 403, 403, ZSAU_DISCONNECT_REQ, -1, -1, {ACT_DEBUG} },
+ {RSP_ZSAU, 403, 403, ZSAU_NULL, 0, 0, {ACT_DISCONNECT} },
+ {RSP_NODEV, 401, 403, -1, 0, 0, {ACT_FAKEHUP} },
{RSP_ERROR, 401,401, -1, 0, 0, {ACT_ABORTHUP}},
{EV_TIMEOUT, 401,403, -1, 0, 0, {ACT_ABORTHUP}},
@@ -1434,11 +1433,12 @@ static void do_action(int action, struct cardstate *cs,
cs->gotfwver = -1;
dev_err(cs->dev, "could not read firmware version.\n");
break;
-#ifdef CONFIG_GIGASET_DEBUG
case ACT_ERROR:
- *p_genresp = 1;
- *p_resp_code = RSP_ERROR;
+ gig_dbg(DEBUG_ANY, "%s: ERROR response in ConState %d",
+ __func__, at_state->ConState);
+ cs->cur_at_seq = SEQ_NONE;
break;
+#ifdef CONFIG_GIGASET_DEBUG
case ACT_TEST:
{
static int count = 3; //2; //1;
--
1.6.2.1.214.ge986c
^ permalink raw reply related
* [PATCH 08/12] gigaset: correct debugging output selection
From: Tilman Schmidt @ 2009-09-18 23:57 UTC (permalink / raw)
To: Karsten Keil, Karsten Keil
Cc: Hansjoerg Lipp, davem, i4ldeveloper, netdev, linux-kernel
In-Reply-To: <20090919-patch-gigaset-00.tilman@imap.cc>
Dump payload data consistently only when DEBUG_STREAM_DUMP debug bit
is set.
Impact: debugging aid
Signed-off-by: Tilman Schmidt <tilman@imap.cc>
---
drivers/isdn/gigaset/isocdata.c | 9 ++++++---
1 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/isdn/gigaset/isocdata.c b/drivers/isdn/gigaset/isocdata.c
index bed38fc..7fd32f0 100644
--- a/drivers/isdn/gigaset/isocdata.c
+++ b/drivers/isdn/gigaset/isocdata.c
@@ -429,7 +429,7 @@ static inline int hdlc_buildframe(struct isowbuf_t *iwb,
return -EAGAIN;
}
- dump_bytes(DEBUG_STREAM, "snd data", in, count);
+ dump_bytes(DEBUG_STREAM_DUMP, "snd data", in, count);
/* bitstuff and checksum input data */
fcs = PPP_INITFCS;
@@ -448,7 +448,6 @@ static inline int hdlc_buildframe(struct isowbuf_t *iwb,
/* put closing flag and repeat byte for flag idle */
isowbuf_putflag(iwb);
end = isowbuf_donewrite(iwb);
- dump_bytes(DEBUG_STREAM_DUMP, "isowbuf", iwb->data, end + 1);
return end;
}
@@ -482,6 +481,8 @@ static inline int trans_buildframe(struct isowbuf_t *iwb,
}
gig_dbg(DEBUG_STREAM, "put %d bytes", count);
+ dump_bytes(DEBUG_STREAM_DUMP, "snd data", in, count);
+
write = iwb->write;
do {
c = bitrev8(*in++);
@@ -583,7 +584,7 @@ static inline void hdlc_done(struct bc_state *bcs)
procskb->tail -= 2;
gig_dbg(DEBUG_ISO, "%s: good frame (%d octets)",
__func__, procskb->len);
- dump_bytes(DEBUG_STREAM,
+ dump_bytes(DEBUG_STREAM_DUMP,
"rcv data", procskb->data, procskb->len);
bcs->hw.bas->goodbytes += procskb->len;
gigaset_rcv_skb(procskb, bcs->cs, bcs);
@@ -878,6 +879,8 @@ static inline void trans_receive(unsigned char *src, unsigned count,
dobytes--;
}
if (dobytes == 0) {
+ dump_bytes(DEBUG_STREAM_DUMP,
+ "rcv data", skb->data, skb->len);
gigaset_rcv_skb(skb, bcs->cs, bcs);
bcs->skb = skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN);
if (!skb) {
--
1.6.2.1.214.ge986c
^ permalink raw reply related
* [PATCH 1/4] Documentation: expand isdn/INTERFACE.CAPI document
From: Tilman Schmidt @ 2009-09-18 23:57 UTC (permalink / raw)
To: Karsten Keil, Karsten Keil; +Cc: davem, i4ldeveloper, netdev, linux-kernel
In-Reply-To: <20090919-patch-capi-0.tilman@imap.cc>
Describe the storage of CAPI messages and payload data in SKBs,
kernelcapi debugging output, and note that send_message() may
in fact be called in interrupt context.
Signed-off-by: Tilman Schmidt <tilman@imap.cc>
---
Documentation/isdn/INTERFACE.CAPI | 68 ++++++++++++++++++++++++++++++++-----
1 files changed, 59 insertions(+), 9 deletions(-)
diff --git a/Documentation/isdn/INTERFACE.CAPI b/Documentation/isdn/INTERFACE.CAPI
index 686e107..e6bb1a7 100644
--- a/Documentation/isdn/INTERFACE.CAPI
+++ b/Documentation/isdn/INTERFACE.CAPI
@@ -60,10 +60,9 @@ open() operation on regular files or character devices.
After a successful return from register_appl(), CAPI messages from the
application may be passed to the driver for the device via calls to the
-send_message() callback function. The CAPI message to send is stored in the
-data portion of an skb. Conversely, the driver may call Kernel CAPI's
-capi_ctr_handle_message() function to pass a received CAPI message to Kernel
-CAPI for forwarding to an application, specifying its ApplID.
+send_message() callback function. Conversely, the driver may call Kernel
+CAPI's capi_ctr_handle_message() function to pass a received CAPI message to
+Kernel CAPI for forwarding to an application, specifying its ApplID.
Deregistration requests (CAPI operation CAPI_RELEASE) from applications are
forwarded as calls to the release_appl() callback function, passing the same
@@ -142,6 +141,7 @@ u16 (*send_message)(struct capi_ctr *ctrlr, struct sk_buff *skb)
to accepting or queueing the message. Errors occurring during the
actual processing of the message should be signaled with an
appropriate reply message.
+ May be called in process or interrupt context.
Calls to this function are not serialized by Kernel CAPI, ie. it must
be prepared to be re-entered.
@@ -154,7 +154,8 @@ read_proc_t *ctr_read_proc
system entry, /proc/capi/controllers/<n>; will be called with a
pointer to the device's capi_ctr structure as the last (data) argument
-Note: Callback functions are never called in interrupt context.
+Note: Callback functions except send_message() are never called in interrupt
+context.
- to be filled in before calling capi_ctr_ready():
@@ -171,14 +172,40 @@ u8 serial[CAPI_SERIAL_LEN]
value to return for CAPI_GET_SERIAL
-4.3 The _cmsg Structure
+4.3 SKBs
+
+CAPI messages are passed between Kernel CAPI and the driver via send_message()
+and capi_ctr_handle_message(), stored in the data portion of a socket buffer
+(skb). Each skb contains a single CAPI message coded according to the CAPI 2.0
+standard.
+
+For the data transfer messages, DATA_B3_REQ and DATA_B3_IND, the actual
+payload data immediately follows the CAPI message itself within the same skb.
+The Data and Data64 parameters are not used for processing. The Data64
+parameter may be omitted by setting the length field of the CAPI message to 22
+instead of 30.
+
+
+4.4 The _cmsg Structure
(declared in <linux/isdn/capiutil.h>)
The _cmsg structure stores the contents of a CAPI 2.0 message in an easily
-accessible form. It contains members for all possible CAPI 2.0 parameters, of
-which only those appearing in the message type currently being processed are
-actually used. Unused members should be set to zero.
+accessible form. It contains members for all possible CAPI 2.0 parameters,
+including subparameters of the Additional Info and B Protocol structured
+parameters, with the following exceptions:
+
+* second Calling party number (CONNECT_IND)
+
+* Data64 (DATA_B3_REQ and DATA_B3_IND)
+
+* Sending complete (subparameter of Additional Info, CONNECT_REQ and INFO_REQ)
+
+* Global Configuration (subparameter of B Protocol, CONNECT_REQ, CONNECT_RESP
+ and SELECT_B_PROTOCOL_REQ)
+
+Only those parameters appearing in the message type currently being processed
+are actually used. Unused members should be set to zero.
Members are named after the CAPI 2.0 standard names of the parameters they
represent. See <linux/isdn/capiutil.h> for the exact spelling. Member data
@@ -297,3 +324,26 @@ char *capi_cmd2str(u8 Command, u8 Subcommand)
be NULL if the command/subcommand is not one of those defined in the
CAPI 2.0 standard.
+
+7. Debugging
+
+The module kernelcapi has a module parameter showcapimsgs controlling some
+debugging output produced by the module. It can only be set when the module is
+loaded, via a parameter "showcapimsgs=<n>" to the modprobe command, either on
+the command line or in the configuration file.
+
+If the lowest bit of showcapimsgs is set, kernelcapi logs controller and
+application up and down events.
+
+In addition, every registered CAPI controller has an associated traceflag
+parameter controlling how CAPI messages sent from and to tha controller are
+logged. The traceflag parameter is initialized with the value of the
+showcapimsgs parameter when the controller is registered, but can later be
+changed via the MANUFACTURER_REQ command KCAPI_CMD_TRACE.
+
+If the value of traceflag is non-zero, CAPI messages are logged.
+DATA_B3 messages are only logged if the value of traceflag is > 2.
+
+If the lowest bit of traceflag is set, only the command/subcommand and message
+length are logged. Otherwise, kernelcapi logs a readable representation of
+the entire message.
--
1.6.2.1.214.ge986c
^ permalink raw reply related
* [PATCH 3/4] isdn: avoid races in capidrv (v2)
From: Tilman Schmidt @ 2009-09-18 23:57 UTC (permalink / raw)
To: Karsten Keil, Karsten Keil; +Cc: davem, i4ldeveloper, netdev, linux-kernel
In-Reply-To: <20090919-patch-capi-0.tilman@imap.cc>
In several places, capidrv sends a CAPI message to the ISDN
device and then updates its internal state accordingly.
If the response message from the device arrives before the
state is updated, it may be rejected or processed incorrectly.
Avoid these races by updating the state before emitting the
message.
Signed-off-by: Tilman Schmidt <tilman@imap.cc>
---
drivers/isdn/capi/capidrv.c | 25 +++++++++++++------------
1 files changed, 13 insertions(+), 12 deletions(-)
diff --git a/drivers/isdn/capi/capidrv.c b/drivers/isdn/capi/capidrv.c
index 6501202..4921eae 100644
--- a/drivers/isdn/capi/capidrv.c
+++ b/drivers/isdn/capi/capidrv.c
@@ -671,8 +671,8 @@ static void n0(capidrv_contr * card, capidrv_ncci * ncci)
NULL, /* Useruserdata */ /* $$$$ */
NULL /* Facilitydataarray */
);
- send_message(card, &cmsg);
plci_change_state(card, ncci->plcip, EV_PLCI_DISCONNECT_REQ);
+ send_message(card, &cmsg);
cmd.command = ISDN_STAT_BHUP;
cmd.driver = card->myid;
@@ -924,8 +924,8 @@ static void handle_incoming_call(capidrv_contr * card, _cmsg * cmsg)
*/
capi_cmsg_answer(cmsg);
cmsg->Reject = 1; /* ignore */
- send_message(card, cmsg);
plci_change_state(card, plcip, EV_PLCI_CONNECT_REJECT);
+ send_message(card, cmsg);
printk(KERN_INFO "capidrv-%d: incoming call %s,%d,%d,%s ignored\n",
card->contrnr,
cmd.parm.setup.phone,
@@ -974,8 +974,8 @@ static void handle_incoming_call(capidrv_contr * card, _cmsg * cmsg)
case 2: /* Call will be rejected. */
capi_cmsg_answer(cmsg);
cmsg->Reject = 2; /* reject call, normal call clearing */
- send_message(card, cmsg);
plci_change_state(card, plcip, EV_PLCI_CONNECT_REJECT);
+ send_message(card, cmsg);
break;
default:
@@ -983,8 +983,8 @@ static void handle_incoming_call(capidrv_contr * card, _cmsg * cmsg)
capi_cmsg_answer(cmsg);
cmsg->Reject = 8; /* reject call,
destination out of order */
- send_message(card, cmsg);
plci_change_state(card, plcip, EV_PLCI_CONNECT_REJECT);
+ send_message(card, cmsg);
break;
}
return;
@@ -1020,8 +1020,8 @@ static void handle_plci(_cmsg * cmsg)
card->bchans[plcip->chan].disconnecting = 1;
plci_change_state(card, plcip, EV_PLCI_DISCONNECT_IND);
capi_cmsg_answer(cmsg);
- send_message(card, cmsg);
plci_change_state(card, plcip, EV_PLCI_DISCONNECT_RESP);
+ send_message(card, cmsg);
break;
case CAPI_DISCONNECT_CONF: /* plci */
@@ -1078,8 +1078,8 @@ static void handle_plci(_cmsg * cmsg)
if (card->bchans[plcip->chan].incoming) {
capi_cmsg_answer(cmsg);
- send_message(card, cmsg);
plci_change_state(card, plcip, EV_PLCI_CONNECT_ACTIVE_IND);
+ send_message(card, cmsg);
} else {
capidrv_ncci *nccip;
capi_cmsg_answer(cmsg);
@@ -1098,13 +1098,14 @@ static void handle_plci(_cmsg * cmsg)
NULL /* NCPI */
);
nccip->msgid = cmsg->Messagenumber;
+ plci_change_state(card, plcip,
+ EV_PLCI_CONNECT_ACTIVE_IND);
+ ncci_change_state(card, nccip, EV_NCCI_CONNECT_B3_REQ);
send_message(card, cmsg);
cmd.command = ISDN_STAT_DCONN;
cmd.driver = card->myid;
cmd.arg = plcip->chan;
card->interface.statcallb(&cmd);
- plci_change_state(card, plcip, EV_PLCI_CONNECT_ACTIVE_IND);
- ncci_change_state(card, nccip, EV_NCCI_CONNECT_B3_REQ);
}
break;
@@ -1193,8 +1194,8 @@ static void handle_ncci(_cmsg * cmsg)
goto notfound;
capi_cmsg_answer(cmsg);
- send_message(card, cmsg);
ncci_change_state(card, nccip, EV_NCCI_CONNECT_B3_ACTIVE_IND);
+ send_message(card, cmsg);
cmd.command = ISDN_STAT_BCONN;
cmd.driver = card->myid;
@@ -1222,8 +1223,8 @@ static void handle_ncci(_cmsg * cmsg)
0, /* Reject */
NULL /* NCPI */
);
- send_message(card, cmsg);
ncci_change_state(card, nccip, EV_NCCI_CONNECT_B3_RESP);
+ send_message(card, cmsg);
break;
}
printk(KERN_ERR "capidrv-%d: no mem for ncci, sorry\n", card->contrnr);
@@ -1299,8 +1300,8 @@ static void handle_ncci(_cmsg * cmsg)
card->bchans[nccip->chan].disconnecting = 1;
ncci_change_state(card, nccip, EV_NCCI_DISCONNECT_B3_IND);
capi_cmsg_answer(cmsg);
- send_message(card, cmsg);
ncci_change_state(card, nccip, EV_NCCI_DISCONNECT_B3_RESP);
+ send_message(card, cmsg);
break;
case CAPI_DISCONNECT_B3_CONF: /* ncci */
@@ -2014,8 +2015,8 @@ static void send_listen(capidrv_contr *card)
card->cipmask,
card->cipmask2,
NULL, NULL);
- send_message(card, &cmdcmsg);
listen_change_state(card, EV_LISTEN_REQ);
+ send_message(card, &cmdcmsg);
}
static void listentimerfunc(unsigned long x)
--
1.6.2.1.214.ge986c
^ permalink raw reply related
* [PATCH] lib/vsprintf.c: Avoid possible unaligned accesses in %pI6c
From: Joe Perches @ 2009-09-18 23:04 UTC (permalink / raw)
To: netdev; +Cc: Jens Rosenboom, David Miller
Jens Rosenboom noticed that a possibly unaligned const char*
is cast to a const struct in6_addr *.
Avoid this at the cost of a struct in6_addr copy on the stack.
Signed-off-by: Joe Perches <joe@perches.com>
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index d320c18..5d299d0 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -671,7 +671,7 @@ static char *ip4_string(char *p, const u8 *addr, bool leading_zeros)
return p;
}
-static char *ip6_compressed_string(char *p, const struct in6_addr *addr)
+static char *ip6_compressed_string(char *p, const char *addr)
{
int i;
int j;
@@ -683,7 +683,12 @@ static char *ip6_compressed_string(char *p, const struct in6_addr *addr)
u8 hi;
u8 lo;
bool needcolon = false;
- bool useIPv4 = ipv6_addr_v4mapped(addr) || ipv6_addr_is_isatap(addr);
+ bool useIPv4;
+ struct in6_addr in6;
+
+ memcpy(&in6, addr, sizeof(struct in6_addr));
+
+ useIPv4 = ipv6_addr_v4mapped(&in6) || ipv6_addr_is_isatap(&in6);
memset(zerolength, 0, sizeof(zerolength));
@@ -695,7 +700,7 @@ static char *ip6_compressed_string(char *p, const struct in6_addr *addr)
/* find position of longest 0 run */
for (i = 0; i < range; i++) {
for (j = i; j < range; j++) {
- if (addr->s6_addr16[j] != 0)
+ if (in6.s6_addr16[j] != 0)
break;
zerolength[i]++;
}
@@ -722,7 +727,7 @@ static char *ip6_compressed_string(char *p, const struct in6_addr *addr)
needcolon = false;
}
/* hex u16 without leading 0s */
- word = ntohs(addr->s6_addr16[i]);
+ word = ntohs(in6.s6_addr16[i]);
hi = word >> 8;
lo = word & 0xff;
if (hi) {
@@ -741,19 +746,19 @@ static char *ip6_compressed_string(char *p, const struct in6_addr *addr)
if (useIPv4) {
if (needcolon)
*p++ = ':';
- p = ip4_string(p, &addr->s6_addr[12], false);
+ p = ip4_string(p, &in6.s6_addr[12], false);
}
*p = '\0';
return p;
}
-static char *ip6_string(char *p, const struct in6_addr *addr, const char *fmt)
+static char *ip6_string(char *p, const char *addr, const char *fmt)
{
int i;
for (i = 0; i < 8; i++) {
- p = pack_hex_byte(p, addr->s6_addr[2 * i]);
- p = pack_hex_byte(p, addr->s6_addr[2 * i + 1]);
+ p = pack_hex_byte(p, *addr++);
+ p = pack_hex_byte(p, *addr++);
if (fmt[0] == 'I' && i != 7)
*p++ = ':';
}
@@ -768,9 +773,9 @@ static char *ip6_addr_string(char *buf, char *end, const u8 *addr,
char ip6_addr[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255")];
if (fmt[0] == 'I' && fmt[2] == 'c')
- ip6_compressed_string(ip6_addr, (const struct in6_addr *)addr);
+ ip6_compressed_string(ip6_addr, addr);
else
- ip6_string(ip6_addr, (const struct in6_addr *)addr, fmt);
+ ip6_string(ip6_addr, addr, fmt);
return string(buf, end, ip6_addr, spec);
}
^ permalink raw reply related
* Re: [PATCH net-next-2.6] bonding: set primary param via sysfs
From: Jay Vosburgh @ 2009-09-18 23:02 UTC (permalink / raw)
To: Jiri Pirko; +Cc: netdev, davem, bonding-devel
In-Reply-To: <20090918121321.GB2801@psychotron.redhat.com>
Jiri Pirko <jpirko@redhat.com> wrote:
>Primary module parameter passed to bonding is pernament. That means if you
>release the primary slave and enslave it again, it becomes the primary slave
>again. But if you set primary slave via sysfs, the primary slave is only set
>once and it's not remembered in bond->params structure. Therefore the setting is
>lost after releasing the primary slave. This simple one-liner fixes this.
>
>Signed-off-by: Jiri Pirko <jpirko@redhat.com>
>
>diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
>index 6044e12..ff449de 100644
>--- a/drivers/net/bonding/bond_sysfs.c
>+++ b/drivers/net/bonding/bond_sysfs.c
>@@ -1182,6 +1182,7 @@ static ssize_t bonding_store_primary(struct device *d,
> ": %s: Setting %s as primary slave.\n",
> bond->dev->name, slave->dev->name);
> bond->primary_slave = slave;
>+ strcpy(bond->params.primary, slave->dev->name);
> bond_select_active_slave(bond);
> goto out;
> }
Looks good, fixes another bug I'd not heard of previously.
Signed-off-by: Jay Vosburgh <fubar@us.ibm.com>
^ permalink raw reply
* Re: [PATCH 1/5] First Patch on TFRC-SP. Copy base files from TFRC
From: gerrit @ 2009-09-18 22:54 UTC (permalink / raw)
To: Ian McDonald; +Cc: Ivo Calado, Gerrit Renker, dccp, netdev
In-Reply-To: <5640c8aa0909142225q73e477fcga99a48c218d10e0b@mail.gmail.com>
Sorry for the delay in replying.
>> One future patch will need to modify this file, but now it's really an
>> exact copy.
>>
>>
> Basically the rule with a patch set is that all the patches should
> make sense together.
>
> It may well be that it makes sense to make a copy, but if you want to
> do this then present it with the patch that then modifies it.
>
I agree with Ian's point. At the moment I can only see patch 5/5 modifying
this file (adding documentation); from my reading of RFC 4828/5622 it seems
not necessary to use 'tfrc_sp' variants of the functions computing X.
The situation will be better as soon as the patches are in their own subtree.
Currently there is a benefit in using separate files: the tfrc library does
not support a sender-based variant of TFRC, hence requires further work
and/or
a decision to support a sender-bsed variant of CCID-3/4 only in an
experimental subtree - this requires input and discussion.
^ permalink raw reply
* Re: fanotify as syscalls
From: Andreas Gruenbacher @ 2009-09-18 22:00 UTC (permalink / raw)
To: Eric Paris
Cc: Jamie Lokier, Linus Torvalds, Evgeniy Polyakov, David Miller,
linux-kernel, linux-fsdevel, netdev, viro, alan, hch
In-Reply-To: <1253307128.2552.21.camel@dhcp231-106.rdu.redhat.com>
On Friday, 18 September 2009 22:52:08 Eric Paris wrote:
> On Thu, 2009-09-17 at 22:07 +0200, Andreas Gruenbacher wrote:
> > From my point of view, "global" events make no sense, and fanotify
> > listeners should register which directories they are interested in (e.g.,
> > include "/", exclude "/proc"). This takes care of chroots and namespaces
> > as well.
>
> While I completely agree that most users don't want global events, the
> antimalware vendors who today, unprotect and hack the syscall table on
> their unsuspecting customer's machines to intercept every read, write,
> open, close, mmap, etc syscall want EXACTLY that.
I understand that "global" is what those guys get today for lack of a
reasonable mechanism, but it's not what anybody can ge given by fanotify: it
conflicts with filesystem namespaces.
Consider running several "virtual machines" in separate namespaces on the same
kernel. With "global" you are forced to run the same global fanotify
listeners everywhere; with per-mount-point listeners, you can choose
between "global" and something more fine-grained by identifying which
vfsmounts you are interested in. (Filesystem namespaces correspond to
vfsmount hierarchies.)
> [...] You still have to exclude /proc and /sys and everything else.
Those are mount points, and so convenient to handle with a per-mount-point
mechanism. No additional kernel code needed.
> [...] Still though, this sounds like an issue for the f_type and f_fsid
> exclusion syscall I say I'm still not settled on.
Those are also obsolete with a per-mount-point mechanism.
Thanks,
Andreas
^ permalink raw reply
* Re: fanotify as syscalls
From: Eric Paris @ 2009-09-18 20:52 UTC (permalink / raw)
To: Andreas Gruenbacher
Cc: Jamie Lokier, Linus Torvalds, Evgeniy Polyakov, David Miller,
linux-kernel, linux-fsdevel, netdev, viro, alan, hch
In-Reply-To: <200909172207.01764.agruen@suse.de>
On Thu, 2009-09-17 at 22:07 +0200, Andreas Gruenbacher wrote:
> From my point of view, "global" events make no sense, and fanotify listeners
> should register which directories they are interested in (e.g., include "/",
> exclude "/proc"). This takes care of chroots and namespaces as well.
While I completely agree that most users don't want global events, the
antimalware vendors who today, unprotect and hack the syscall table on
their unsuspecting customer's machines to intercept every read, write,
open, close, mmap, etc syscall want EXACTLY that. They'd been asking
for a way to get this information for quite some time now. The largest
vendors in this market have agreed the interface (well, when it was a
socket interface that I talked about for so long) should meet their
needs.
Subtree watching / isn't any different or better, just harder and more
complex to implement. You still have to exclude /proc and /sys and
everything else. Just like one must with a global listener. Still
though, this sounds like an issue for the f_type and f_fsid exclusion
syscall I say I'm still not settled on. Not and issue with the basis of
fanotify or with the 3 proposed syscalls.
Jamie, do you see a problem with what I have been asking for review on
or see a problem with extending it moving forward?
Linus, do you see the value of 'yet another notification scheme' ?
-Eric
^ permalink raw reply
* Re: [Bonding-devel] [PATCH net-next-2.6] bonding: set primary param via sysfs
From: Nicolas de Pesloüan @ 2009-09-18 20:21 UTC (permalink / raw)
To: Jiri Pirko; +Cc: netdev, fubar, davem, bonding-devel
In-Reply-To: <20090918121321.GB2801@psychotron.redhat.com>
Jiri Pirko wrote:
> Primary module parameter passed to bonding is pernament. That means if you
typo in "permanent".
> release the primary slave and enslave it again, it becomes the primary slave
> again. But if you set primary slave via sysfs, the primary slave is only set
> once and it's not remembered in bond->params structure. Therefore the setting is
> lost after releasing the primary slave. This simple one-liner fixes this.
You patch also has the side effect of fixing this strange behavior:
If you move the primary slave from one bond device to another one, it becomes
the primary for this other bond device, ignoring what you might have set as the
primary for this other bond device.
#modprobe bonding mode=active-backup primary=eth0
#echo +eth0 > /sys/class/net/bond0/bonding/slaves
#cat /sys/class/net/bond0/bonding/primary
eth0
#echo -eth0 > /sys/class/net/bond0/bonding/slaves
#echo +eth1 > /sys/class/net/bond1/bonding/slaves
#echo eth1 > /sys/class/net/bond1/bonding/primary
#cat /sys/class/net/bond1/bonding/primary
eth1
#echo +eth0 > /sys/class/net/bond1/bonding/slaves
#cat /sys/class/net/bond1/bonding/primary
eth0
=> Primary just changed, for no good reason.
Can someone imagine that some current configurations rely on this incredible
side effect ?
Nicolas.
> Signed-off-by: Jiri Pirko <jpirko@redhat.com>
>
> diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
> index 6044e12..ff449de 100644
> --- a/drivers/net/bonding/bond_sysfs.c
> +++ b/drivers/net/bonding/bond_sysfs.c
> @@ -1182,6 +1182,7 @@ static ssize_t bonding_store_primary(struct device *d,
> ": %s: Setting %s as primary slave.\n",
> bond->dev->name, slave->dev->name);
> bond->primary_slave = slave;
> + strcpy(bond->params.primary, slave->dev->name);
> bond_select_active_slave(bond);
> goto out;
> }
^ permalink raw reply
* [patch 6/6] isdn: eicon, return on error
From: akpm @ 2009-09-18 19:53 UTC (permalink / raw)
To: isdn; +Cc: netdev, akpm, jirislaby, armin
From: Jiri Slaby <jirislaby@gmail.com>
When diva_strace_read_uint returns an error, return even from
process_idi_event, because l2_state is uninitialized.
Signed-off-by: Jiri Slaby <jirislaby@gmail.com>
Cc: Karsten Keil <isdn@linux-pingi.de>
Acked-by: Armin Schindler <armin@melware.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---
drivers/isdn/hardware/eicon/maintidi.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff -puN drivers/isdn/hardware/eicon/maintidi.c~isdn-eicon-return-on-error drivers/isdn/hardware/eicon/maintidi.c
--- a/drivers/isdn/hardware/eicon/maintidi.c~isdn-eicon-return-on-error
+++ a/drivers/isdn/hardware/eicon/maintidi.c
@@ -959,8 +959,9 @@ static int process_idi_event (diva_strac
}
if (!strncmp("State\\Layer2 No1", path, pVar->path_length)) {
char* tmp = &pLib->lines[0].pInterface->Layer2[0];
- dword l2_state;
- diva_strace_read_uint (pVar, &l2_state);
+ dword l2_state;
+ if (diva_strace_read_uint(pVar, &l2_state))
+ return -1;
switch (l2_state) {
case 0:
_
^ permalink raw reply
* [patch 5/6] isdn: eicon, use offsetof
From: akpm @ 2009-09-18 19:53 UTC (permalink / raw)
To: isdn; +Cc: netdev, akpm, jirislaby, armin
From: Jiri Slaby <jirislaby@gmail.com>
Use offsetof instead of explicit implementation.
* fixes bug with omitted & like:
len = (byte)(((T30_INFO *) 0)->station_id + 20)
* avoids compiler warnings with wrong sizes (pointer-to-char cast):
len = (byte)(&(((T30_INFO *) 0)->universal_6));
* cleans up the code
Signed-off-by: Jiri Slaby <jirislaby@gmail.com>
Cc: Karsten Keil <isdn@linux-pingi.de>
Acked-by: Armin Schindler <armin@melware.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---
drivers/isdn/hardware/eicon/message.c | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff -puN drivers/isdn/hardware/eicon/message.c~isdn-eicon-use-offsetof drivers/isdn/hardware/eicon/message.c
--- a/drivers/isdn/hardware/eicon/message.c~isdn-eicon-use-offsetof
+++ a/drivers/isdn/hardware/eicon/message.c
@@ -2692,7 +2692,7 @@ static byte connect_b3_req(dword Id, wor
if (!(fax_control_bits & T30_CONTROL_BIT_MORE_DOCUMENTS)
|| (fax_feature_bits & T30_FEATURE_BIT_MORE_DOCUMENTS))
{
- len = (byte)(&(((T30_INFO *) 0)->universal_6));
+ len = offsetof(T30_INFO, universal_6);
fax_info_change = false;
if (ncpi->length >= 4)
{
@@ -2754,7 +2754,7 @@ static byte connect_b3_req(dword Id, wor
for (i = 0; i < w; i++)
((T30_INFO *)(plci->fax_connect_info_buffer))->station_id[i] = fax_parms[4].info[1+i];
((T30_INFO *)(plci->fax_connect_info_buffer))->head_line_len = 0;
- len = (byte)(((T30_INFO *) 0)->station_id + 20);
+ len = offsetof(T30_INFO, station_id) + 20;
w = fax_parms[5].length;
if (w > 20)
w = 20;
@@ -2788,7 +2788,7 @@ static byte connect_b3_req(dword Id, wor
}
else
{
- len = (byte)(&(((T30_INFO *) 0)->universal_6));
+ len = offsetof(T30_INFO, universal_6);
}
fax_info_change = true;
@@ -2892,7 +2892,7 @@ static byte connect_b3_res(dword Id, wor
&& (plci->nsf_control_bits & T30_NSF_CONTROL_BIT_ENABLE_NSF)
&& (plci->nsf_control_bits & T30_NSF_CONTROL_BIT_NEGOTIATE_RESP))
{
- len = ((byte)(((T30_INFO *) 0)->station_id + 20));
+ len = offsetof(T30_INFO, station_id) + 20;
if (plci->fax_connect_info_length < len)
{
((T30_INFO *)(plci->fax_connect_info_buffer))->station_id_len = 0;
@@ -3802,7 +3802,7 @@ static byte manufacturer_res(dword Id, w
break;
}
ncpi = &m_parms[1];
- len = ((byte)(((T30_INFO *) 0)->station_id + 20));
+ len = offsetof(T30_INFO, station_id) + 20;
if (plci->fax_connect_info_length < len)
{
((T30_INFO *)(plci->fax_connect_info_buffer))->station_id_len = 0;
@@ -6844,7 +6844,7 @@ static void nl_ind(PLCI *plci)
if ((plci->requested_options_conn | plci->requested_options | a->requested_options_table[plci->appl->Id-1])
& ((1L << PRIVATE_FAX_SUB_SEP_PWD) | (1L << PRIVATE_FAX_NONSTANDARD)))
{
- i = ((word)(((T30_INFO *) 0)->station_id + 20)) + ((T30_INFO *)plci->NL.RBuffer->P)->head_line_len;
+ i = offsetof(T30_INFO, station_id) + 20 + ((T30_INFO *)plci->NL.RBuffer->P)->head_line_len;
while (i < plci->NL.RBuffer->length)
plci->ncpi_buffer[++len] = plci->NL.RBuffer->P[i++];
}
@@ -7236,7 +7236,7 @@ static void nl_ind(PLCI *plci)
{
plci->RData[1].P = plci->RData[0].P;
plci->RData[1].PLength = plci->RData[0].PLength;
- plci->RData[0].P = v120_header_buffer + (-((int) v120_header_buffer) & 3);
+ plci->RData[0].P = v120_header_buffer + (-((unsigned long)v120_header_buffer) & 3);
if ((plci->NL.RBuffer->P[0] & V120_HEADER_EXTEND_BIT) || (plci->NL.RLength == 1))
plci->RData[0].PLength = 1;
else
@@ -8473,7 +8473,7 @@ static word add_b23(PLCI *plci, API_PARS
fax_control_bits |= T30_CONTROL_BIT_ACCEPT_SEL_POLLING;
}
len = nlc[0];
- pos = ((byte)(((T30_INFO *) 0)->station_id + 20));
+ pos = offsetof(T30_INFO, station_id) + 20;
if (pos < plci->fax_connect_info_length)
{
for (i = 1 + plci->fax_connect_info_buffer[pos]; i != 0; i--)
@@ -8525,7 +8525,7 @@ static word add_b23(PLCI *plci, API_PARS
}
PUT_WORD(&(((T30_INFO *)&nlc[1])->control_bits_low), fax_control_bits);
- len = ((byte)(((T30_INFO *) 0)->station_id + 20));
+ len = offsetof(T30_INFO, station_id) + 20;
for (i = 0; i < len; i++)
plci->fax_connect_info_buffer[i] = nlc[1+i];
((T30_INFO *) plci->fax_connect_info_buffer)->head_line_len = 0;
_
^ permalink raw reply
* [patch 3/6] isdn: fix netjet build errors
From: akpm @ 2009-09-18 19:53 UTC (permalink / raw)
To: isdn; +Cc: netdev, akpm, randy.dunlap
From: Randy Dunlap <randy.dunlap@oracle.com>
Fix netjet driver link errors when ISDN_I4L is not enabled:
drivers/built-in.o: In function `mode_tiger':
netjet.c:(.text+0x325dc8): undefined reference to `isdnhdlc_rcv_init'
netjet.c:(.text+0x325dd5): undefined reference to `isdnhdlc_out_init'
drivers/built-in.o: In function `fill_dma':
netjet.c:(.text+0x325fb6): undefined reference to `isdnhdlc_encode'
drivers/built-in.o: In function `read_dma':
netjet.c:(.text+0x32631a): undefined reference to `isdnhdlc_decode'
drivers/built-in.o: In function `nj_irq':
netjet.c:(.text+0x326e01): undefined reference to `isdnhdlc_encode'
or move isdnhdlc.c to some other sub-dir..
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Cc: Karsten Keil <isdn@linux-pingi.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---
drivers/isdn/hardware/mISDN/Kconfig | 1 +
1 file changed, 1 insertion(+)
diff -puN drivers/isdn/hardware/mISDN/Kconfig~isdn-fix-netjet-build-errors drivers/isdn/hardware/mISDN/Kconfig
--- a/drivers/isdn/hardware/mISDN/Kconfig~isdn-fix-netjet-build-errors
+++ a/drivers/isdn/hardware/mISDN/Kconfig
@@ -78,6 +78,7 @@ config MISDN_NETJET
depends on PCI
select MISDN_IPAC
select ISDN_HDLC
+ select ISDN_I4L # so that make will recurse into sub-dir.
help
Enable support for Traverse Technologies NETJet PCI cards.
_
^ permalink raw reply
* [patch 4/6] mISDN: fix reversed if in st_own_ctrl()
From: akpm @ 2009-09-18 19:53 UTC (permalink / raw)
To: isdn; +Cc: netdev, akpm, error27
From: Dan Carpenter <error27@gmail.com>
The current code probably returns -EINVAL a lot. Otherwise it would oops.
Compile tested only. Found by smatch (http://repo.or.cz/w/smatch.git).
Signed-off-by: Dan Carpenter <error27@gmail.com>
Cc: Karsten Keil <isdn@linux-pingi.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---
drivers/isdn/mISDN/stack.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff -puN drivers/isdn/mISDN/stack.c~misdn-fix-reversed-if-in-st_own_ctrl drivers/isdn/mISDN/stack.c
--- a/drivers/isdn/mISDN/stack.c~misdn-fix-reversed-if-in-st_own_ctrl
+++ a/drivers/isdn/mISDN/stack.c
@@ -364,7 +364,7 @@ add_layer2(struct mISDNchannel *ch, stru
static int
st_own_ctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
{
- if (!ch->st || ch->st->layer1)
+ if (!ch->st || !ch->st->layer1)
return -EINVAL;
return ch->st->layer1->ctrl(ch->st->layer1, cmd, arg);
}
_
^ permalink raw reply
* Re: [PATCH] i2400m: minimal ethtool support
From: Inaky Perez-Gonzalez @ 2009-09-18 19:57 UTC (permalink / raw)
To: Dan Williams; +Cc: netdev, wimax@linuxwimax.org
In-Reply-To: <1253217974.11454.12.camel@localhost.localdomain>
On Thu, 2009-09-17 at 13:06 -0700, Dan Williams wrote:
> Add minimal ethtool support for carrier detection.
>
> Signed-off-by: Dan Williams <dcbw@redhat.com>
Merged, thanks
--
-- Inaky
^ permalink raw reply
* [PATCH net-next-2.6 v2] bonding: introduce primary_reselect option
From: Jiri Pirko @ 2009-09-18 19:53 UTC (permalink / raw)
To: netdev; +Cc: davem, fubar, bonding-devel, nicolas.2p.debian
(updated 4)
In some cases there is not desirable to switch back to primary interface when
it's link recovers and rather stay with currently active one. We need to avoid
packetloss as much as we can in some cases. This is solved by introducing
primary_reselect option. Note that enslaved primary slave is set as current
active no matter what.
Signed-off-by: Jiri Pirko <jpirko@redhat.com>
diff --git a/Documentation/networking/bonding.txt b/Documentation/networking/bonding.txt
index d5181ce..fd650e0 100644
--- a/Documentation/networking/bonding.txt
+++ b/Documentation/networking/bonding.txt
@@ -614,6 +614,32 @@ primary
The primary option is only valid for active-backup mode.
+primary_reselect
+
+ Specifies the behavior of the current active slave when the primary was
+ down and comes back up. This option is designed to prevent
+ flip-flopping between the primary slave and other slaves. The possible
+ values and their respective effects are:
+
+ always or 0 (default)
+
+ The primary slave becomes the active slave whenever it comes
+ back up.
+
+ better or 1
+
+ The primary slave becomes the active slave when it comes back
+ up, if the speed and duplex of the primary slave is better
+ than the speed and duplex of the current active slave.
+
+ failure or 2
+
+ The primary slave becomes the active slave only if the current
+ active slave fails and the primary slave is up.
+
+ When no slave are active, if the primary comes back up, it becomes the
+ active slave, regardless of the value of primary_reselect.
+
updelay
Specifies the time, in milliseconds, to wait before enabling a
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 699bfdd..8f8a6cc 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -94,6 +94,7 @@ static int downdelay;
static int use_carrier = 1;
static char *mode;
static char *primary;
+static char *primary_reselect;
static char *lacp_rate;
static char *ad_select;
static char *xmit_hash_policy;
@@ -126,6 +127,14 @@ MODULE_PARM_DESC(mode, "Mode of operation : 0 for balance-rr, "
"6 for balance-alb");
module_param(primary, charp, 0);
MODULE_PARM_DESC(primary, "Primary network device to use");
+module_param(primary_reselect, charp, 0);
+MODULE_PARM_DESC(primary_reselect, "Reselect primary slave "
+ "once it comes up; "
+ "0 for always (default), "
+ "1 for only if speed of primary is "
+ "better, "
+ "2 for only on active slave "
+ "failure");
module_param(lacp_rate, charp, 0);
MODULE_PARM_DESC(lacp_rate, "LACPDU tx rate to request from 802.3ad partner "
"(slow/fast)");
@@ -200,6 +209,13 @@ const struct bond_parm_tbl fail_over_mac_tbl[] = {
{ NULL, -1},
};
+const struct bond_parm_tbl pri_reselect_tbl[] = {
+{ "always", BOND_PRI_RESELECT_ALWAYS},
+{ "better", BOND_PRI_RESELECT_BETTER},
+{ "failure", BOND_PRI_RESELECT_FAILURE},
+{ NULL, -1},
+};
+
struct bond_parm_tbl ad_select_tbl[] = {
{ "stable", BOND_AD_STABLE},
{ "bandwidth", BOND_AD_BANDWIDTH},
@@ -1070,6 +1086,25 @@ out:
}
+static bool bond_should_change_active(struct bonding *bond)
+{
+ struct slave *prim = bond->primary_slave;
+ struct slave *curr = bond->curr_active_slave;
+
+ if (!prim || !curr || curr->link != BOND_LINK_UP)
+ return true;
+ if (bond->force_primary) {
+ bond->force_primary = false;
+ return true;
+ }
+ if (bond->params.primary_reselect == BOND_PRI_RESELECT_BETTER &&
+ (prim->speed < curr->speed ||
+ (prim->speed == curr->speed && prim->duplex <= curr->duplex)))
+ return false;
+ if (bond->params.primary_reselect == BOND_PRI_RESELECT_FAILURE)
+ return false;
+ return true;
+}
/**
* find_best_interface - select the best available slave to be the active one
@@ -1094,7 +1129,8 @@ static struct slave *bond_find_best_slave(struct bonding *bond)
}
if ((bond->primary_slave) &&
- bond->primary_slave->link == BOND_LINK_UP) {
+ bond->primary_slave->link == BOND_LINK_UP &&
+ bond_should_change_active(bond)) {
new_active = bond->primary_slave;
}
@@ -1675,8 +1711,10 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
if (USES_PRIMARY(bond->params.mode) && bond->params.primary[0]) {
/* if there is a primary slave, remember it */
- if (strcmp(bond->params.primary, new_slave->dev->name) == 0)
+ if (strcmp(bond->params.primary, new_slave->dev->name) == 0) {
bond->primary_slave = new_slave;
+ bond->force_primary = true;
+ }
}
write_lock_bh(&bond->curr_slave_lock);
@@ -4643,7 +4681,7 @@ int bond_parse_parm(const char *buf, const struct bond_parm_tbl *tbl)
static int bond_check_params(struct bond_params *params)
{
- int arp_validate_value, fail_over_mac_value;
+ int arp_validate_value, fail_over_mac_value, primary_reselect_value;
/*
* Convert string parameters.
@@ -4942,6 +4980,20 @@ static int bond_check_params(struct bond_params *params)
primary = NULL;
}
+ if (primary && primary_reselect) {
+ primary_reselect_value = bond_parse_parm(primary_reselect,
+ pri_reselect_tbl);
+ if (primary_reselect_value == -1) {
+ pr_err(DRV_NAME
+ ": Error: Invalid primary_reselect \"%s\"\n",
+ primary_reselect ==
+ NULL ? "NULL" : primary_reselect);
+ return -EINVAL;
+ }
+ } else {
+ primary_reselect_value = BOND_PRI_RESELECT_ALWAYS;
+ }
+
if (fail_over_mac) {
fail_over_mac_value = bond_parse_parm(fail_over_mac,
fail_over_mac_tbl);
@@ -4973,6 +5025,7 @@ static int bond_check_params(struct bond_params *params)
params->use_carrier = use_carrier;
params->lacp_fast = lacp_fast;
params->primary[0] = 0;
+ params->primary_reselect = primary_reselect_value;
params->fail_over_mac = fail_over_mac_value;
if (primary) {
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index 6044e12..42c44f2 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -1212,6 +1212,61 @@ static DEVICE_ATTR(primary, S_IRUGO | S_IWUSR,
bonding_show_primary, bonding_store_primary);
/*
+ * Show and set the primary_reselect flag.
+ */
+static ssize_t bonding_show_primary_reselect(struct device *d,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct bonding *bond = to_bond(d);
+
+ return sprintf(buf, "%s %d\n",
+ pri_reselect_tbl[bond->params.primary_reselect].modename,
+ bond->params.primary_reselect);
+}
+
+static ssize_t bonding_store_primary_reselect(struct device *d,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int new_value, ret = count;
+ struct bonding *bond = to_bond(d);
+
+ if (!rtnl_trylock())
+ return restart_syscall();
+
+ new_value = bond_parse_parm(buf, pri_reselect_tbl);
+ if (new_value < 0) {
+ pr_err(DRV_NAME
+ ": %s: Ignoring invalid primary_reselect value %.*s.\n",
+ bond->dev->name,
+ (int) strlen(buf) - 1, buf);
+ ret = -EINVAL;
+ goto out;
+ } else {
+ bond->params.primary_reselect = new_value;
+ pr_info(DRV_NAME ": %s: setting primary_reselect to %s (%d).\n",
+ bond->dev->name, pri_reselect_tbl[new_value].modename,
+ new_value);
+ if (new_value == BOND_PRI_RESELECT_ALWAYS ||
+ new_value == BOND_PRI_RESELECT_BETTER) {
+ bond->force_primary = true;
+ read_lock(&bond->lock);
+ write_lock_bh(&bond->curr_slave_lock);
+ bond_select_active_slave(bond);
+ write_unlock_bh(&bond->curr_slave_lock);
+ read_unlock(&bond->lock);
+ }
+ }
+out:
+ rtnl_unlock();
+ return ret;
+}
+static DEVICE_ATTR(primary_reselect, S_IRUGO | S_IWUSR,
+ bonding_show_primary_reselect,
+ bonding_store_primary_reselect);
+
+/*
* Show and set the use_carrier flag.
*/
static ssize_t bonding_show_carrier(struct device *d,
@@ -1500,6 +1555,7 @@ static struct attribute *per_bond_attrs[] = {
&dev_attr_num_unsol_na.attr,
&dev_attr_miimon.attr,
&dev_attr_primary.attr,
+ &dev_attr_primary_reselect.attr,
&dev_attr_use_carrier.attr,
&dev_attr_active_slave.attr,
&dev_attr_mii_status.attr,
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index 6824771..b5b1530 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -131,6 +131,7 @@ struct bond_params {
int lacp_fast;
int ad_select;
char primary[IFNAMSIZ];
+ int primary_reselect;
__be32 arp_targets[BOND_MAX_ARP_TARGETS];
};
@@ -190,6 +191,7 @@ struct bonding {
struct slave *curr_active_slave;
struct slave *current_arp_slave;
struct slave *primary_slave;
+ bool force_primary;
s32 slave_cnt; /* never change this value outside the attach/detach wrappers */
rwlock_t lock;
rwlock_t curr_slave_lock;
@@ -258,6 +260,10 @@ static inline bool bond_is_lb(const struct bonding *bond)
|| bond->params.mode == BOND_MODE_ALB;
}
+#define BOND_PRI_RESELECT_ALWAYS 0
+#define BOND_PRI_RESELECT_BETTER 1
+#define BOND_PRI_RESELECT_FAILURE 2
+
#define BOND_FOM_NONE 0
#define BOND_FOM_ACTIVE 1
#define BOND_FOM_FOLLOW 2
@@ -348,6 +354,7 @@ extern const struct bond_parm_tbl bond_mode_tbl[];
extern const struct bond_parm_tbl xmit_hashtype_tbl[];
extern const struct bond_parm_tbl arp_validate_tbl[];
extern const struct bond_parm_tbl fail_over_mac_tbl[];
+extern const struct bond_parm_tbl pri_reselect_tbl[];
extern struct bond_parm_tbl ad_select_tbl[];
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
^ permalink raw reply related
* [patch 1/6] isdn: hisax, fix lock imbalance
From: akpm @ 2009-09-18 19:53 UTC (permalink / raw)
To: isdn; +Cc: netdev, akpm, jirislaby, Karsten-Keil
From: Jiri Slaby <jirislaby@gmail.com>
Add omittted unlocks to 2 functions.
Signed-off-by: Jiri Slaby <jirislaby@gmail.com>
Cc: Karsten Keil <Karsten-Keil@t-online.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---
drivers/isdn/hisax/amd7930_fn.c | 1 +
drivers/isdn/hisax/icc.c | 1 +
2 files changed, 2 insertions(+)
diff -puN drivers/isdn/hisax/amd7930_fn.c~isdn-hisax-fix-lock-imbalance drivers/isdn/hisax/amd7930_fn.c
--- a/drivers/isdn/hisax/amd7930_fn.c~isdn-hisax-fix-lock-imbalance
+++ a/drivers/isdn/hisax/amd7930_fn.c
@@ -594,6 +594,7 @@ Amd7930_l1hw(struct PStack *st, int pr,
if (cs->debug & L1_DEB_WARN)
debugl1(cs, "Amd7930: l1hw: l2l1 tx_skb exist this shouldn't happen");
skb_queue_tail(&cs->sq, skb);
+ spin_unlock_irqrestore(&cs->lock, flags);
break;
}
if (cs->debug & DEB_DLOG_HEX)
diff -puN drivers/isdn/hisax/icc.c~isdn-hisax-fix-lock-imbalance drivers/isdn/hisax/icc.c
--- a/drivers/isdn/hisax/icc.c~isdn-hisax-fix-lock-imbalance
+++ a/drivers/isdn/hisax/icc.c
@@ -468,6 +468,7 @@ ICC_l1hw(struct PStack *st, int pr, void
if (cs->debug & L1_DEB_WARN)
debugl1(cs, " l2l1 tx_skb exist this shouldn't happen");
skb_queue_tail(&cs->sq, skb);
+ spin_unlock_irqrestore(&cs->lock, flags);
break;
}
if (cs->debug & DEB_DLOG_HEX)
_
^ permalink raw reply
* [patch 2/6] hfc_usb: fix read buffer overflow
From: akpm @ 2009-09-18 19:53 UTC (permalink / raw)
To: isdn; +Cc: netdev, akpm, roel.kluin
From: Roel Kluin <roel.kluin@gmail.com>
Check whether index is within bounds before testing the element.
Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
Cc: Karsten Keil <isdn@linux-pingi.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---
drivers/isdn/hisax/hfc_usb.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff -puN drivers/isdn/hisax/hfc_usb.c~hfc_usb-fix-read-buffer-overflow drivers/isdn/hisax/hfc_usb.c
--- a/drivers/isdn/hisax/hfc_usb.c~hfc_usb-fix-read-buffer-overflow
+++ a/drivers/isdn/hisax/hfc_usb.c
@@ -817,8 +817,8 @@ collect_rx_frame(usb_fifo * fifo, __u8 *
}
/* we have a complete hdlc packet */
if (finish) {
- if ((!fifo->skbuff->data[fifo->skbuff->len - 1])
- && (fifo->skbuff->len > 3)) {
+ if (fifo->skbuff->len > 3 &&
+ !fifo->skbuff->data[fifo->skbuff->len - 1]) {
if (fifon == HFCUSB_D_RX) {
DBG(HFCUSB_DBG_DCHANNEL,
_
^ permalink raw reply
* [patch 1/1] net: fix CONFIG_NET=n build on sparc64
From: akpm @ 2009-09-18 19:52 UTC (permalink / raw)
To: davem; +Cc: netdev, akpm
From: Andrew Morton <akpm@linux-foundation.org>
sparc64 allnoconfig:
arch/sparc/kernel/built-in.o(.text+0x134e0): In function `sys32_recvfrom':
: undefined reference to `compat_sys_recvfrom'
arch/sparc/kernel/built-in.o(.text+0x134e4): In function `sys32_recvfrom':
: undefined reference to `compat_sys_recvfrom'
Cc: "David S. Miller" <davem@davemloft.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---
kernel/sys_ni.c | 1 +
1 file changed, 1 insertion(+)
diff -puN kernel/sys_ni.c~net-fix-config_net=n-build-on-sparc64 kernel/sys_ni.c
--- a/kernel/sys_ni.c~net-fix-config_net=n-build-on-sparc64
+++ a/kernel/sys_ni.c
@@ -49,6 +49,7 @@ cond_syscall(sys_sendmsg);
cond_syscall(compat_sys_sendmsg);
cond_syscall(sys_recvmsg);
cond_syscall(compat_sys_recvmsg);
+cond_syscall(compat_sys_recvfrom);
cond_syscall(sys_socketcall);
cond_syscall(sys_futex);
cond_syscall(compat_sys_futex);
_
^ permalink raw reply
* Re: [PATCH net-next-2.6] bonding: introduce primary_reselect option
From: Jiri Pirko @ 2009-09-18 19:52 UTC (permalink / raw)
To: Nicolas de Pesloüan; +Cc: netdev, davem, fubar, bonding-devel
In-Reply-To: <4AB3E03B.3070205@free.fr>
Fri, Sep 18, 2009 at 09:32:11PM CEST, nicolas.2p.debian@free.fr wrote:
> Jiri Pirko a écrit :
>> (updated 3)
>>
>> In some cases there is not desirable to switch back to primary interface when
>> it's link recovers and rather stay with currently active one. We need to avoid
>> packetloss as much as we can in some cases. This is solved by introducing
>> primary_reselect option. Note that enslaved primary slave is set as current
>> active no matter what.
>>
>> Signed-off-by: Jiri Pirko <jpirko@redhat.com>
>>
>> diff --git a/Documentation/networking/bonding.txt b/Documentation/networking/bonding.txt
>> index d5181ce..fd650e0 100644
>> --- a/Documentation/networking/bonding.txt
>> +++ b/Documentation/networking/bonding.txt
>> @@ -614,6 +614,32 @@ primary
>> The primary option is only valid for active-backup mode.
>> +primary_reselect
>> +
>> + Specifies the behavior of the current active slave when the primary was
>> + down and comes back up. This option is designed to prevent
>> + flip-flopping between the primary slave and other slaves. The possible
>> + values and their respective effects are:
>> +
>> + always or 0 (default)
>> +
>> + The primary slave becomes the active slave whenever it comes
>> + back up.
>> +
>> + better or 1
>> +
>> + The primary slave becomes the active slave when it comes back
>> + up, if the speed and duplex of the primary slave is better
>> + than the speed and duplex of the current active slave.
>> +
>> + failure or 2
>> +
>> + The primary slave becomes the active slave only if the current
>> + active slave fails and the primary slave is up.
>> +
>> + When no slave are active, if the primary comes back up, it becomes the
>> + active slave, regardless of the value of primary_reselect.
>> +
>> updelay
>> Specifies the time, in milliseconds, to wait before enabling a
>> diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
>> index 699bfdd..1127361 100644
>> --- a/drivers/net/bonding/bond_main.c
>> +++ b/drivers/net/bonding/bond_main.c
>> @@ -94,6 +94,7 @@ static int downdelay;
>> static int use_carrier = 1;
>> static char *mode;
>> static char *primary;
>> +static char *primary_reselect;
>> static char *lacp_rate;
>> static char *ad_select;
>> static char *xmit_hash_policy;
>> @@ -126,6 +127,13 @@ MODULE_PARM_DESC(mode, "Mode of operation : 0 for balance-rr, "
>> "6 for balance-alb");
>> module_param(primary, charp, 0);
>> MODULE_PARM_DESC(primary, "Primary network device to use");
>> +module_param(primary_reselect, charp, 0);
>> +MODULE_PARM_DESC(primary_reselect, "Reselect primary slave "
>> + "once it comes up; "
>> + "0 for always (default), "
>> + "1 for only if speed of primary is not "
>> + "better, "
>> + "2 for never");
>
> You should remove "not" for option value 1 and use the word failure for
> option value 2.
>
> MODULE_PARM_DESC(primary_reselect, "Reselect primary slave "
> "once it comes up; "
> "0 for always (default), "
> "1 for only if speed of primary is "
> "better, "
> "2 for only on active slave "
> "failure");
Okay, I wasn't sure how to put it here. This sounds good, going to resend.
Thanks Nicolas.
>
> Apart from this small detail, this sounds good for me.
>
>> module_param(lacp_rate, charp, 0);
>> MODULE_PARM_DESC(lacp_rate, "LACPDU tx rate to request from 802.3ad partner "
>> "(slow/fast)");
>> @@ -200,6 +208,13 @@ const struct bond_parm_tbl fail_over_mac_tbl[] = {
>> { NULL, -1},
>> };
>> +const struct bond_parm_tbl pri_reselect_tbl[] = {
>> +{ "always", BOND_PRI_RESELECT_ALWAYS},
>> +{ "better", BOND_PRI_RESELECT_BETTER},
>> +{ "failure", BOND_PRI_RESELECT_FAILURE},
>> +{ NULL, -1},
>> +};
>> +
>> struct bond_parm_tbl ad_select_tbl[] = {
>> { "stable", BOND_AD_STABLE},
>> { "bandwidth", BOND_AD_BANDWIDTH},
>> @@ -1070,6 +1085,25 @@ out:
>> }
>> +static bool bond_should_change_active(struct bonding *bond)
>> +{
>> + struct slave *prim = bond->primary_slave;
>> + struct slave *curr = bond->curr_active_slave;
>> +
>> + if (!prim || !curr || curr->link != BOND_LINK_UP)
>> + return true;
>> + if (bond->force_primary) {
>> + bond->force_primary = false;
>> + return true;
>> + }
>> + if (bond->params.primary_reselect == BOND_PRI_RESELECT_BETTER &&
>> + (prim->speed < curr->speed ||
>> + (prim->speed == curr->speed && prim->duplex <= curr->duplex)))
>> + return false;
>> + if (bond->params.primary_reselect == BOND_PRI_RESELECT_FAILURE)
>> + return false;
>> + return true;
>> +}
>> /**
>> * find_best_interface - select the best available slave to be the active one
>> @@ -1094,7 +1128,8 @@ static struct slave *bond_find_best_slave(struct bonding *bond)
>> }
>> if ((bond->primary_slave) &&
>> - bond->primary_slave->link == BOND_LINK_UP) {
>> + bond->primary_slave->link == BOND_LINK_UP &&
>> + bond_should_change_active(bond)) {
>> new_active = bond->primary_slave;
>> }
>> @@ -1675,8 +1710,10 @@ int bond_enslave(struct net_device *bond_dev,
>> struct net_device *slave_dev)
>> if (USES_PRIMARY(bond->params.mode) && bond->params.primary[0]) {
>> /* if there is a primary slave, remember it */
>> - if (strcmp(bond->params.primary, new_slave->dev->name) == 0)
>> + if (strcmp(bond->params.primary, new_slave->dev->name) == 0) {
>> bond->primary_slave = new_slave;
>> + bond->force_primary = true;
>> + }
>> }
>> write_lock_bh(&bond->curr_slave_lock);
>> @@ -4643,7 +4680,7 @@ int bond_parse_parm(const char *buf, const struct bond_parm_tbl *tbl)
>> static int bond_check_params(struct bond_params *params)
>> {
>> - int arp_validate_value, fail_over_mac_value;
>> + int arp_validate_value, fail_over_mac_value, primary_reselect_value;
>> /*
>> * Convert string parameters.
>> @@ -4942,6 +4979,20 @@ static int bond_check_params(struct bond_params *params)
>> primary = NULL;
>> }
>> + if (primary && primary_reselect) {
>> + primary_reselect_value = bond_parse_parm(primary_reselect,
>> + pri_reselect_tbl);
>> + if (primary_reselect_value == -1) {
>> + pr_err(DRV_NAME
>> + ": Error: Invalid primary_reselect \"%s\"\n",
>> + primary_reselect ==
>> + NULL ? "NULL" : primary_reselect);
>> + return -EINVAL;
>> + }
>> + } else {
>> + primary_reselect_value = BOND_PRI_RESELECT_ALWAYS;
>> + }
>> +
>> if (fail_over_mac) {
>> fail_over_mac_value = bond_parse_parm(fail_over_mac,
>> fail_over_mac_tbl);
>> @@ -4973,6 +5024,7 @@ static int bond_check_params(struct bond_params *params)
>> params->use_carrier = use_carrier;
>> params->lacp_fast = lacp_fast;
>> params->primary[0] = 0;
>> + params->primary_reselect = primary_reselect_value;
>> params->fail_over_mac = fail_over_mac_value;
>> if (primary) {
>> diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
>> index 6044e12..42c44f2 100644
>> --- a/drivers/net/bonding/bond_sysfs.c
>> +++ b/drivers/net/bonding/bond_sysfs.c
>> @@ -1212,6 +1212,61 @@ static DEVICE_ATTR(primary, S_IRUGO | S_IWUSR,
>> bonding_show_primary, bonding_store_primary);
>> /*
>> + * Show and set the primary_reselect flag.
>> + */
>> +static ssize_t bonding_show_primary_reselect(struct device *d,
>> + struct device_attribute *attr,
>> + char *buf)
>> +{
>> + struct bonding *bond = to_bond(d);
>> +
>> + return sprintf(buf, "%s %d\n",
>> + pri_reselect_tbl[bond->params.primary_reselect].modename,
>> + bond->params.primary_reselect);
>> +}
>> +
>> +static ssize_t bonding_store_primary_reselect(struct device *d,
>> + struct device_attribute *attr,
>> + const char *buf, size_t count)
>> +{
>> + int new_value, ret = count;
>> + struct bonding *bond = to_bond(d);
>> +
>> + if (!rtnl_trylock())
>> + return restart_syscall();
>> +
>> + new_value = bond_parse_parm(buf, pri_reselect_tbl);
>> + if (new_value < 0) {
>> + pr_err(DRV_NAME
>> + ": %s: Ignoring invalid primary_reselect value %.*s.\n",
>> + bond->dev->name,
>> + (int) strlen(buf) - 1, buf);
>> + ret = -EINVAL;
>> + goto out;
>> + } else {
>> + bond->params.primary_reselect = new_value;
>> + pr_info(DRV_NAME ": %s: setting primary_reselect to %s (%d).\n",
>> + bond->dev->name, pri_reselect_tbl[new_value].modename,
>> + new_value);
>> + if (new_value == BOND_PRI_RESELECT_ALWAYS ||
>> + new_value == BOND_PRI_RESELECT_BETTER) {
>> + bond->force_primary = true;
>> + read_lock(&bond->lock);
>> + write_lock_bh(&bond->curr_slave_lock);
>> + bond_select_active_slave(bond);
>> + write_unlock_bh(&bond->curr_slave_lock);
>> + read_unlock(&bond->lock);
>> + }
>> + }
>> +out:
>> + rtnl_unlock();
>> + return ret;
>> +}
>> +static DEVICE_ATTR(primary_reselect, S_IRUGO | S_IWUSR,
>> + bonding_show_primary_reselect,
>> + bonding_store_primary_reselect);
>> +
>> +/*
>> * Show and set the use_carrier flag.
>> */
>> static ssize_t bonding_show_carrier(struct device *d,
>> @@ -1500,6 +1555,7 @@ static struct attribute *per_bond_attrs[] = {
>> &dev_attr_num_unsol_na.attr,
>> &dev_attr_miimon.attr,
>> &dev_attr_primary.attr,
>> + &dev_attr_primary_reselect.attr,
>> &dev_attr_use_carrier.attr,
>> &dev_attr_active_slave.attr,
>> &dev_attr_mii_status.attr,
>> diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
>> index 6824771..b5b1530 100644
>> --- a/drivers/net/bonding/bonding.h
>> +++ b/drivers/net/bonding/bonding.h
>> @@ -131,6 +131,7 @@ struct bond_params {
>> int lacp_fast;
>> int ad_select;
>> char primary[IFNAMSIZ];
>> + int primary_reselect;
>> __be32 arp_targets[BOND_MAX_ARP_TARGETS];
>> };
>> @@ -190,6 +191,7 @@ struct bonding {
>> struct slave *curr_active_slave;
>> struct slave *current_arp_slave;
>> struct slave *primary_slave;
>> + bool force_primary;
>> s32 slave_cnt; /* never change this value outside the attach/detach wrappers */
>> rwlock_t lock;
>> rwlock_t curr_slave_lock;
>> @@ -258,6 +260,10 @@ static inline bool bond_is_lb(const struct bonding *bond)
>> || bond->params.mode == BOND_MODE_ALB;
>> }
>> +#define BOND_PRI_RESELECT_ALWAYS 0
>> +#define BOND_PRI_RESELECT_BETTER 1
>> +#define BOND_PRI_RESELECT_FAILURE 2
>> +
>> #define BOND_FOM_NONE 0
>> #define BOND_FOM_ACTIVE 1
>> #define BOND_FOM_FOLLOW 2
>> @@ -348,6 +354,7 @@ extern const struct bond_parm_tbl bond_mode_tbl[];
>> extern const struct bond_parm_tbl xmit_hashtype_tbl[];
>> extern const struct bond_parm_tbl arp_validate_tbl[];
>> extern const struct bond_parm_tbl fail_over_mac_tbl[];
>> +extern const struct bond_parm_tbl pri_reselect_tbl[];
>> extern struct bond_parm_tbl ad_select_tbl[];
>> #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
>>
>
> Nicolas.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox