[patch 9/9] s390: ctc online/offline bug fix. From: Peter Tiedemann <ptiedem@xxxxxxxxxx> ctc network driver changes: - Properly initialize ccw array. This fixes the stray oopses after an online/offline cycle. - Correct check for already existing channel. - Add missing kfrees. Signed-off-by: Martin Schwidefsky <schwidefsky@xxxxxxxxxx> diffstat: drivers/s390/net/ctcmain.c | 21 +++++++++++---------- 1 files changed, 11 insertions(+), 10 deletions(-) diff -urN linux-2.6/drivers/s390/net/ctcmain.c linux-2.6-patched/drivers/s390/net/ctcmain.c --- linux-2.6/drivers/s390/net/ctcmain.c 2005-03-02 08:38:37.000000000 +0100 +++ linux-2.6-patched/drivers/s390/net/ctcmain.c 2005-03-02 17:00:16.000000000 +0100 @@ -1,5 +1,5 @@ /* - * $Id: ctcmain.c,v 1.68 2004/12/27 09:25:27 heicarst Exp $ + * $Id: ctcmain.c,v 1.69 2005/02/27 19:46:44 ptiedem Exp $ * * CTC / ESCON network driver * @@ -7,6 +7,7 @@ * Author(s): Fritz Elfert (elfert@xxxxxxxxxx, felfert@xxxxxxxxxxxx) * Fixes by : Jochen Röhrig (roehrig@xxxxxxxxxx) * Arnaldo Carvalho de Melo <acme@xxxxxxxxxxxxxxxx> + Peter Tiedemann (ptiedem@xxxxxxxxxx) * Driver Model stuff by : Cornelia Huck <cohuck@xxxxxxxxxx> * * Documentation used: @@ -36,7 +37,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * RELEASE-TAG: CTC/ESCON network driver $Revision: 1.68 $ + * RELEASE-TAG: CTC/ESCON network driver $Revision: 1.69 $ * */ @@ -1894,13 +1895,15 @@ return -1; } memset(ch, 0, sizeof (struct channel)); - if ((ch->ccw = (struct ccw1 *) kmalloc(sizeof (struct ccw1) * 8, + if ((ch->ccw = (struct ccw1 *) kmalloc(8*sizeof(struct ccw1), GFP_KERNEL | GFP_DMA)) == NULL) { kfree(ch); ctc_pr_warn("ctc: Out of memory in add_channel\n"); return -1; } + memset(ch->ccw, 0, 8*sizeof(struct ccw1)); // assure all flags and counters are reset + /** * "static" ccws are used in the following way: * @@ -1914,21 +1917,17 @@ * 4: write (idal allocated on every write). * 5: nop * ccw[6..7] (Channel program for initial channel setup): - * 3: set extended mode - * 4: nop + * 6: set extended mode + * 7: nop * * ch->ccw[0..5] are initialized in ch_action_start because * the channel's direction is yet unknown here. */ ch->ccw[6].cmd_code = CCW_CMD_SET_EXTENDED; ch->ccw[6].flags = CCW_FLAG_SLI; - ch->ccw[6].count = 0; - ch->ccw[6].cda = 0; ch->ccw[7].cmd_code = CCW_CMD_NOOP; ch->ccw[7].flags = CCW_FLAG_SLI; - ch->ccw[7].count = 0; - ch->ccw[7].cda = 0; ch->cdev = cdev; snprintf(ch->id, CTC_ID_SIZE, "ch-%s", cdev->dev.bus_id); @@ -1955,7 +1954,7 @@ memset(ch->irb, 0, sizeof (struct irb)); while (*c && less_than((*c)->id, ch->id)) c = &(*c)->next; - if (!strncmp((*c)->id, ch->id, CTC_ID_SIZE)) { + if (*c && (!strncmp((*c)->id, ch->id, CTC_ID_SIZE))) { ctc_pr_debug( "ctc: add_channel: device %s already in list, " "using old entry\n", (*c)->id); @@ -2011,6 +2010,8 @@ dev_kfree_skb(ch->trans_skb); } kfree(ch->ccw); + kfree(ch->irb); + kfree(ch); return; } c = &((*c)->next); - : send the line "unsubscribe linux-net" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html