2000-11-11 21:10:36

by Dag Brattli

[permalink] [raw]
Subject: [patch] patch-2.4.0-test10-irda10 (was: Re: The IrDA patches)

Linus,

Here are the new IrDA patches for Linux-2.4.0-test10. Please apply them to
your latest 2.4 code. If you decide to apply them, then I suggest you start
with the first one (irda1.diff) and work your way to the last one
(irda24.diff) since most of them are not commutative.

The name of this patch is irda10.diff.

(Many thanks to Jean Tourrilhes for splitting up the big patch)

[FEATURE] : Add a new feature to the IrDA stack
[CORRECT] : Fix to have the correct/expected behaviour
[CRITICA] : Fix potential kernel crash
[OUPS ] : Error that will be fixed in a later patch

irda10.diff :
-----------------
o [CRITICA] Update skb handling (Add skb_get() and kfree_skb())

diff -urpN old-linux/net/irda/irlap.c linux/net/irda/irlap.c
--- old-linux/net/irda/irlap.c Thu Nov 9 14:47:22 2000
+++ linux/net/irda/irlap.c Thu Nov 9 14:47:40 2000
@@ -232,7 +232,8 @@ void irlap_connect_indication(struct irl
ASSERT(self->magic == LAP_MAGIC, return;);

irlap_init_qos_capabilities(self, NULL); /* No user QoS! */
-
+
+ skb_get(skb); /*LEVEL4*/
irlmp_link_connect_indication(self->notify.instance, self->saddr,
self->daddr, &self->qos_tx, skb);
}
@@ -248,6 +249,7 @@ void irlap_connect_response(struct irlap
IRDA_DEBUG(4, __FUNCTION__ "()\n");

irlap_do_event(self, CONNECT_RESPONSE, skb, NULL);
+ kfree_skb(skb);
}

/*
@@ -292,6 +294,7 @@ void irlap_connect_confirm(struct irlap_
ASSERT(self != NULL, return;);
ASSERT(self->magic == LAP_MAGIC, return;);

+ skb_get(skb); /*LEVEL4*/
irlmp_link_connect_confirm(self->notify.instance, &self->qos_tx, skb);
}

@@ -310,6 +313,7 @@ void irlap_data_indication(struct irlap_

#ifdef CONFIG_IRDA_COMPRESSION
if (self->qos_tx.compression.value) {
+ skb_get(skb); /*LEVEL4*/
skb = irlap_decompress_frame(self, skb);
if (!skb) {
IRDA_DEBUG(1, __FUNCTION__ "(), Decompress error!\n");
@@ -317,6 +321,7 @@ void irlap_data_indication(struct irlap_
}
}
#endif
+ skb_get(skb); /*LEVEL4*/
irlmp_link_data_indication(self->notify.instance, skb, unreliable);
}

@@ -373,6 +378,7 @@ void irlap_data_request(struct irlap_cb
ASSERT(skb != NULL, return;);
}
irlap_do_event(self, SEND_I_CMD, skb, NULL);
+ kfree_skb(skb);
} else
skb_queue_tail(&self->txq, skb);
}
@@ -422,6 +428,7 @@ void irlap_unitdata_indication(struct ir
/* Hide LAP header from IrLMP layer */
skb_pull(skb, LAP_ADDR_HEADER+LAP_CTRL_HEADER);

+ skb_get(skb); /*LEVEL4*/
irlmp_link_unitdata_indication(self->notify.instance, skb);
}
#endif /* CONFIG_IRDA_ULTRA */
diff -urpN old-linux/net/irda/irlap_event.c linux/net/irda/irlap_event.c
--- old-linux/net/irda/irlap_event.c Thu Nov 9 14:47:22 2000
+++ linux/net/irda/irlap_event.c Thu Nov 9 14:47:40 2000
@@ -230,7 +230,7 @@ void irlap_do_event(struct irlap_cb *sel

if (!self || self->magic != LAP_MAGIC)
return;
-
+
IRDA_DEBUG(3, __FUNCTION__ "(), event = %s, state = %s\n",
irlap_event[event], irlap_state[self->state]);

@@ -252,6 +252,7 @@ void irlap_do_event(struct irlap_cb *sel
while ((skb = skb_dequeue(&self->txq)) != NULL) {
ret = (*state[self->state])(self, SEND_I_CMD,
skb, NULL);
+ kfree_skb(skb);
if (ret == -EPROTO)
break; /* Try again later! */
}
@@ -351,12 +352,11 @@ static int irlap_state_ndm(struct irlap_
self->caddr = info->caddr;

irlap_next_state(self, LAP_CONN);
-
+
irlap_connect_indication(self, skb);
} else {
IRDA_DEBUG(0, __FUNCTION__ "(), SNRM frame does not "
"contain an I field!\n");
- dev_kfree_skb(skb);
}
break;
case DISCOVERY_REQUEST:
@@ -410,14 +410,13 @@ static int irlap_state_ndm(struct irlap_
irlap_start_query_timer(self, QUERY_TIMEOUT*info->S);
irlap_next_state(self, LAP_REPLY);
}
- dev_kfree_skb(skb);
break;
#ifdef CONFIG_IRDA_ULTRA
case SEND_UI_FRAME:
/* Only allowed to repeat an operation twice */
for (i=0; ((i<2) && (self->media_busy == FALSE)); i++) {
skb = skb_dequeue(&self->txq_ultra);
- if (skb)
+ if (skb)
irlap_send_ui_frame(self, skb, CBROADCAST,
CMD_FRAME);
else
@@ -433,7 +432,6 @@ static int irlap_state_ndm(struct irlap_
if (info->caddr != CBROADCAST) {
IRDA_DEBUG(0, __FUNCTION__
"(), not a broadcast frame!\n");
- dev_kfree_skb(skb);
} else
irlap_unitdata_indication(self, skb);
break;
@@ -447,19 +445,14 @@ static int irlap_state_ndm(struct irlap_
* will only be used to send out the same info as the cmd
*/
irlap_send_test_frame(self, CBROADCAST, info->daddr, skb);
- dev_kfree_skb(skb);
break;
case RECV_TEST_RSP:
IRDA_DEBUG(0, __FUNCTION__ "() not implemented!\n");
- dev_kfree_skb(skb);
break;
default:
IRDA_DEBUG(2, __FUNCTION__ "(), Unknown event %s\n",
irlap_event[event]);

- if (skb)
- dev_kfree_skb(skb);
-
ret = -1;
break;
}
@@ -492,7 +485,6 @@ static int irlap_state_query(struct irla
WARNING(__FUNCTION__ "(), discovery log is gone! "
"maybe the discovery timeout has been set to "
"short?\n");
- dev_kfree_skb(skb);
break;
}
hashbin_insert(self->discovery_log,
@@ -502,7 +494,6 @@ static int irlap_state_query(struct irla
/* Keep state */
/* irlap_next_state(self, LAP_QUERY); */

- dev_kfree_skb(skb);
break;
case SLOT_TIMER_EXPIRED:
if (self->s < self->S) {
@@ -537,9 +528,6 @@ static int irlap_state_query(struct irla
IRDA_DEBUG(2, __FUNCTION__ "(), Unknown event %s\n",
irlap_event[event]);

- if (skb)
- dev_kfree_skb(skb);
-
ret = -1;
break;
}
@@ -595,15 +583,11 @@ static int irlap_state_reply(struct irla
self->frame_sent = TRUE;
irlap_next_state(self, LAP_REPLY);
}
- dev_kfree_skb(skb);
break;
default:
IRDA_DEBUG(1, __FUNCTION__ "(), Unknown event %d, %s\n", event,
irlap_event[event]);

- if (skb)
- dev_kfree_skb(skb);
-
ret = -1;
break;
}
@@ -665,14 +649,12 @@ static int irlap_state_conn(struct irlap
irlap_start_wd_timer(self, self->wd_timeout);
irlap_next_state(self, LAP_NRM_S);

- dev_kfree_skb(skb);
break;
case RECV_DISCOVERY_XID_CMD:
IRDA_DEBUG(3, __FUNCTION__
"(), event RECV_DISCOVER_XID_CMD!\n");
irlap_next_state(self, LAP_NDM);

- dev_kfree_skb(skb);
break;
case DISCONNECT_REQUEST:
irlap_send_dm_frame(self);
@@ -682,9 +664,6 @@ static int irlap_state_conn(struct irlap
IRDA_DEBUG(1, __FUNCTION__ "(), Unknown event %d, %s\n", event,
irlap_event[event]);

- if (skb)
- dev_kfree_skb(skb);
-
ret = -1;
break;
}
@@ -766,7 +745,6 @@ static int irlap_state_setup(struct irla
irlap_start_wd_timer(self, self->wd_timeout);
} else {
/* We just ignore the other device! */
- dev_kfree_skb(skb);
irlap_next_state(self, LAP_SETUP);
}
break;
@@ -803,14 +781,11 @@ static int irlap_state_setup(struct irla
irlap_next_state(self, LAP_NDM);

irlap_disconnect_indication(self, LAP_DISC_INDICATION);
- dev_kfree_skb(skb);
break;
default:
IRDA_DEBUG(1, __FUNCTION__ "(), Unknown event %d, %s\n", event,
irlap_event[event]);
- if (skb)
- dev_kfree_skb(skb);
-
+
ret = -1;
break;
}
@@ -860,8 +835,7 @@ static int irlap_state_xmit_p(struct irl
IRDA_DEBUG(4, __FUNCTION__
"(), Not allowed to transmit more "
"bytes!\n");
- skb_queue_head(&self->txq, skb);
-
+ skb_queue_head(&self->txq, skb_get(skb));
/*
* We should switch state to LAP_NRM_P, but
* that is not possible since we must be sure
@@ -900,7 +874,7 @@ static int irlap_state_xmit_p(struct irl
} else {
IRDA_DEBUG(4, __FUNCTION__
"(), Unable to send! remote busy?\n");
- skb_queue_head(&self->txq, skb);
+ skb_queue_head(&self->txq, skb_get(skb));

/*
* The next ret is important, because it tells
@@ -929,9 +903,6 @@ static int irlap_state_xmit_p(struct irl
IRDA_DEBUG(0, __FUNCTION__ "(), Unknown event %s\n",
irlap_event[event]);

- if (skb)
- dev_kfree_skb(skb);
-
ret = -EINVAL;
break;
}
@@ -964,7 +935,6 @@ static int irlap_state_pclose(struct irl
irlap_next_state(self, LAP_NDM);

irlap_disconnect_indication(self, LAP_DISC_INDICATION);
- dev_kfree_skb(skb);
break;
case FINAL_TIMER_EXPIRED:
if (self->retry_count < self->N3) {
@@ -985,9 +955,6 @@ static int irlap_state_pclose(struct irl
default:
IRDA_DEBUG(1, __FUNCTION__ "(), Unknown event %d\n", event);

- if (skb)
- dev_kfree_skb(skb);
-
ret = -1;
break;
}
@@ -1041,7 +1008,7 @@ static int irlap_state_nrm_p(struct irla

/* Keep state, do not move this line */
irlap_next_state(self, LAP_NRM_P);
-
+
irlap_data_indication(self, skb, FALSE);
} else {
del_timer(&self->final_timer);
@@ -1065,7 +1032,7 @@ static int irlap_state_nrm_p(struct irla
* upper layers
*/
irlap_next_state(self, LAP_XMIT_P);
-
+
irlap_data_indication(self, skb, FALSE);

/* This is the last frame */
@@ -1102,7 +1069,6 @@ static int irlap_state_nrm_p(struct irla
irlap_start_final_timer(self, self->final_timeout);
irlap_next_state(self, LAP_NRM_P);
}
- dev_kfree_skb(skb);
break;
}
/*
@@ -1124,7 +1090,7 @@ static int irlap_state_nrm_p(struct irla

/* Keep state, do not move this line */
irlap_next_state(self, LAP_NRM_P);
-
+
irlap_data_indication(self, skb, FALSE);
} else {
/*
@@ -1142,7 +1108,7 @@ static int irlap_state_nrm_p(struct irla

/* Keep state, do not move this line!*/
irlap_next_state(self, LAP_NRM_P);
-
+
irlap_data_indication(self, skb, FALSE);
}
break;
@@ -1171,7 +1137,6 @@ static int irlap_state_nrm_p(struct irla

self->ack_required = FALSE;
}
- dev_kfree_skb(skb);
break;
}

@@ -1193,7 +1158,6 @@ static int irlap_state_nrm_p(struct irla

self->xmitflag = FALSE;
}
- dev_kfree_skb(skb);
break;
}
IRDA_DEBUG(1, __FUNCTION__ "(), Not implemented!\n");
@@ -1209,6 +1173,7 @@ static int irlap_state_nrm_p(struct irla
} else {
del_timer(&self->final_timer);
irlap_data_indication(self, skb, TRUE);
+ printk(__FUNCTION__ "(): RECV_UI_FRAME: next state %s\n", irlap_state[self->state]);
irlap_start_poll_timer(self, self->poll_timeout);
}
break;
@@ -1270,7 +1235,6 @@ static int irlap_state_nrm_p(struct irla
irlap_disconnect_indication(self, LAP_RESET_INDICATION);
self->xmitflag = TRUE;
}
- dev_kfree_skb(skb);
break;
case RECV_RNR_RSP:
ASSERT(info != NULL, return -1;);
@@ -1285,14 +1249,12 @@ static int irlap_state_nrm_p(struct irla

/* Start poll timer */
irlap_start_poll_timer(self, self->poll_timeout);
- dev_kfree_skb(skb);
break;
case RECV_FRMR_RSP:
del_timer(&self->final_timer);
self->xmitflag = TRUE;
irlap_next_state(self, LAP_RESET_WAIT);
irlap_reset_indication(self);
- dev_kfree_skb(skb);
break;
case FINAL_TIMER_EXPIRED:
/*
@@ -1357,7 +1319,6 @@ static int irlap_state_nrm_p(struct irla
} else
irlap_resend_rejected_frames(self, CMD_FRAME);
irlap_start_final_timer(self, self->final_timeout);
- dev_kfree_skb(skb);
break;
case RECV_SREJ_RSP:
irlap_update_nr_received(self, info->nr);
@@ -1367,7 +1328,6 @@ static int irlap_state_nrm_p(struct irla
} else
irlap_resend_rejected_frame(self, CMD_FRAME);
irlap_start_final_timer(self, self->final_timeout);
- dev_kfree_skb(skb);
break;
case RECV_RD_RSP:
IRDA_DEBUG(0, __FUNCTION__ "(), RECV_RD_RSP\n");
@@ -1381,8 +1341,6 @@ static int irlap_state_nrm_p(struct irla
default:
IRDA_DEBUG(1, __FUNCTION__ "(), Unknown event %s\n",
irlap_event[event]);
- if (skb)
- dev_kfree_skb(skb);

ret = -1;
break;
@@ -1430,8 +1388,6 @@ static int irlap_state_reset_wait(struct
default:
IRDA_DEBUG(1, __FUNCTION__ "(), Unknown event %s\n",
irlap_event[event]);
- if (skb)
- dev_kfree_skb(skb);

ret = -1;
break;
@@ -1467,7 +1423,6 @@ static int irlap_state_reset(struct irla

irlap_disconnect_indication(self, LAP_NO_RESPONSE);

- dev_kfree_skb(skb);
break;
case RECV_UA_RSP:
del_timer(&self->final_timer);
@@ -1483,7 +1438,6 @@ static int irlap_state_reset(struct irla

irlap_start_poll_timer(self, self->poll_timeout);

- dev_kfree_skb(skb);
break;
case FINAL_TIMER_EXPIRED:
if (self->retry_count < 3) {
@@ -1522,13 +1476,10 @@ static int irlap_state_reset(struct irla
IRDA_DEBUG(0, __FUNCTION__
"(), SNRM frame contained an I field!\n");
}
- dev_kfree_skb(skb);
break;
default:
IRDA_DEBUG(1, __FUNCTION__ "(), Unknown event %s\n",
irlap_event[event]);
- if (skb)
- dev_kfree_skb(skb);

ret = -1;
break;
@@ -1566,7 +1517,7 @@ static int irlap_state_xmit_s(struct irl
* speed and turn-around-time.
*/
if (skb->len > self->bytes_left) {
- skb_queue_head(&self->txq, skb);
+ skb_queue_head(&self->txq, skb_get(skb));
/*
* Switch to NRM_S, this is only possible
* when we are in secondary mode, since we
@@ -1600,7 +1551,7 @@ static int irlap_state_xmit_s(struct irl
}
} else {
IRDA_DEBUG(2, __FUNCTION__ "(), Unable to send!\n");
- skb_queue_head(&self->txq, skb);
+ skb_queue_head(&self->txq, skb_get(skb));
ret = -EPROTO;
}
break;
@@ -1613,8 +1564,6 @@ static int irlap_state_xmit_s(struct irl
default:
IRDA_DEBUG(2, __FUNCTION__ "(), Unknown event %s\n",
irlap_event[event]);
- if (skb)
- dev_kfree_skb(skb);

ret = -EINVAL;
break;
@@ -1676,7 +1625,7 @@ static int irlap_state_nrm_s(struct irla
#endif
/* Keep state, do not move this line */
irlap_next_state(self, LAP_NRM_S);
-
+
irlap_data_indication(self, skb, FALSE);
break;
} else {
@@ -1739,7 +1688,6 @@ static int irlap_state_nrm_s(struct irla

irlap_start_wd_timer(self, self->wd_timeout);
}
- dev_kfree_skb(skb);
break;
}

@@ -1778,7 +1726,7 @@ static int irlap_state_nrm_s(struct irla

/* Keep state, do not move this line */
irlap_next_state(self, LAP_NRM_S);
-
+
irlap_data_indication(self, skb, FALSE);
irlap_start_wd_timer(self, self->wd_timeout);
}
@@ -1787,11 +1735,9 @@ static int irlap_state_nrm_s(struct irla

if (ret == NR_INVALID) {
IRDA_DEBUG(0, "NRM_S, NR_INVALID not implemented!\n");
- dev_kfree_skb(skb);
}
if (ret == NS_INVALID) {
IRDA_DEBUG(0, "NRM_S, NS_INVALID not implemented!\n");
- dev_kfree_skb(skb);
}
break;
case RECV_UI_FRAME:
@@ -1870,7 +1816,6 @@ static int irlap_state_nrm_s(struct irla
IRDA_DEBUG(1, __FUNCTION__
"(), invalid nr not implemented!\n");
}
- dev_kfree_skb(skb);
break;
case RECV_SNRM_CMD:
/* SNRM frame is not allowed to contain an I-field */
@@ -1885,7 +1830,6 @@ static int irlap_state_nrm_s(struct irla
"(), SNRM frame contained an I-field!\n");

}
- dev_kfree_skb(skb);
break;
case RECV_REJ_CMD:
irlap_update_nr_received(self, info->nr);
@@ -1895,7 +1839,6 @@ static int irlap_state_nrm_s(struct irla
} else
irlap_resend_rejected_frames(self, CMD_FRAME);
irlap_start_wd_timer(self, self->wd_timeout);
- dev_kfree_skb(skb);
break;
case RECV_SREJ_CMD:
irlap_update_nr_received(self, info->nr);
@@ -1905,7 +1848,6 @@ static int irlap_state_nrm_s(struct irla
} else
irlap_resend_rejected_frame(self, CMD_FRAME);
irlap_start_wd_timer(self, self->wd_timeout);
- dev_kfree_skb(skb);
break;
case WD_TIMER_EXPIRED:
/*
@@ -1944,7 +1886,6 @@ static int irlap_state_nrm_s(struct irla
irlap_apply_default_connection_parameters(self);

irlap_disconnect_indication(self, LAP_DISC_INDICATION);
- dev_kfree_skb(skb);
break;
case RECV_DISCOVERY_XID_CMD:
irlap_wait_min_turn_around(self, &self->qos_tx);
@@ -1953,7 +1894,6 @@ static int irlap_state_nrm_s(struct irla
irlap_start_wd_timer(self, self->wd_timeout);
irlap_next_state(self, LAP_NRM_S);

- dev_kfree_skb(skb);
break;
case RECV_TEST_CMD:
/* Remove test frame header */
@@ -1964,13 +1904,10 @@ static int irlap_state_nrm_s(struct irla

/* Send response (info will be copied) */
irlap_send_test_frame(self, self->caddr, info->daddr, skb);
- dev_kfree_skb(skb);
break;
default:
IRDA_DEBUG(1, __FUNCTION__ "(), Unknown event %d, (%s)\n",
event, irlap_event[event]);
- if (skb)
- dev_kfree_skb(skb);

ret = -EINVAL;
break;
@@ -2005,7 +1942,6 @@ static int irlap_state_sclose(struct irl
irlap_apply_default_connection_parameters(self);

irlap_disconnect_indication(self, LAP_DISC_INDICATION);
- dev_kfree_skb(skb);
break;
case RECV_DM_RSP:
/* Always switch state before calling upper layers */
@@ -2015,7 +1951,6 @@ static int irlap_state_sclose(struct irl
irlap_apply_default_connection_parameters(self);

irlap_disconnect_indication(self, LAP_DISC_INDICATION);
- dev_kfree_skb(skb);
break;
case WD_TIMER_EXPIRED:
irlap_apply_default_connection_parameters(self);
@@ -2025,9 +1960,7 @@ static int irlap_state_sclose(struct irl
default:
IRDA_DEBUG(1, __FUNCTION__ "(), Unknown event %d, (%s)\n",
event, irlap_event[event]);
- if (skb)
- dev_kfree_skb(skb);
-
+
ret = -EINVAL;
break;
}
@@ -2064,8 +1997,6 @@ static int irlap_state_reset_check( stru
default:
IRDA_DEBUG(1, __FUNCTION__ "(), Unknown event %d, (%s)\n",
event, irlap_event[event]);
- if (skb)
- dev_kfree_skb(skb);

ret = -EINVAL;
break;
diff -urpN old-linux/net/irda/irlap_frame.c linux/net/irda/irlap_frame.c
--- old-linux/net/irda/irlap_frame.c Thu Jan 6 14:46:18 2000
+++ linux/net/irda/irlap_frame.c Thu Nov 9 14:47:40 2000
@@ -164,7 +164,6 @@ static void irlap_recv_snrm_cmd(struct i
if ((info->caddr == 0x00) || (info->caddr == 0xfe)) {
IRDA_DEBUG(3, __FUNCTION__
"(), invalid connection address!\n");
- dev_kfree_skb(skb);
return;
}

@@ -175,13 +174,13 @@ static void irlap_recv_snrm_cmd(struct i
/* Only accept if addressed directly to us */
if (info->saddr != self->saddr) {
IRDA_DEBUG(2, __FUNCTION__ "(), not addressed to us!\n");
- dev_kfree_skb(skb);
return;
}
irlap_do_event(self, RECV_SNRM_CMD, skb, info);
- } else
+ } else {
/* Signal that this SNRM frame does not contain and I-field */
irlap_do_event(self, RECV_SNRM_CMD, skb, NULL);
+ }
}

/*
@@ -408,13 +407,11 @@ static void irlap_recv_discovery_xid_rsp
if ((info->saddr != self->saddr) && (info->saddr != BROADCAST)) {
IRDA_DEBUG(0, __FUNCTION__
"(), frame is not addressed to us!\n");
- dev_kfree_skb(skb);
return;
}

if ((discovery = kmalloc(sizeof(discovery_t), GFP_ATOMIC)) == NULL) {
WARNING(__FUNCTION__ "(), kmalloc failed!\n");
- dev_kfree_skb(skb);
return;
}
memset(discovery, 0, sizeof(discovery_t));
@@ -476,7 +473,6 @@ static void irlap_recv_discovery_xid_cmd
if ((info->saddr != self->saddr) && (info->saddr != BROADCAST)) {
IRDA_DEBUG(0, __FUNCTION__
"(), frame is not addressed to us!\n");
- dev_kfree_skb(skb);
return;
}

@@ -512,7 +508,6 @@ static void irlap_recv_discovery_xid_cmd
discovery = kmalloc(sizeof(discovery_t), GFP_ATOMIC);
if (!discovery) {
WARNING(__FUNCTION__ "(), unable to malloc!\n");
- dev_kfree_skb(skb);
return;
}

@@ -541,7 +536,7 @@ static void irlap_recv_discovery_xid_cmd
info->discovery = discovery;
} else
info->discovery = NULL;
-
+
irlap_do_event(self, RECV_DISCOVERY_XID_CMD, skb, info);
}

@@ -734,7 +729,6 @@ void irlap_send_data_primary(struct irla
/* Copy buffer */
tx_skb = skb_clone(skb, GFP_ATOMIC);
if (tx_skb == NULL) {
- dev_kfree_skb(skb);
return;
}

@@ -747,7 +741,7 @@ void irlap_send_data_primary(struct irla
/*
* Insert frame in store, in case of retransmissions
*/
- skb_queue_tail(&self->wx_list, skb);
+ skb_queue_tail(&self->wx_list, skb_get(skb));

self->vs = (self->vs + 1) % 8;
self->ack_required = FALSE;
@@ -756,7 +750,7 @@ void irlap_send_data_primary(struct irla
irlap_send_i_frame( self, tx_skb, CMD_FRAME);
} else {
IRDA_DEBUG(4, __FUNCTION__ "(), sending unreliable frame\n");
- irlap_send_ui_frame(self, skb, self->caddr, CMD_FRAME);
+ irlap_send_ui_frame(self, skb_get(skb), self->caddr, CMD_FRAME);
self->window -= 1;
}
}
@@ -781,7 +775,6 @@ void irlap_send_data_primary_poll(struct
/* Copy buffer */
tx_skb = skb_clone(skb, GFP_ATOMIC);
if (tx_skb == NULL) {
- dev_kfree_skb(skb);
return;
}

@@ -794,7 +787,7 @@ void irlap_send_data_primary_poll(struct
/*
* Insert frame in store, in case of retransmissions
*/
- skb_queue_tail(&self->wx_list, skb);
+ skb_queue_tail(&self->wx_list, skb_get(skb));

/*
* Set poll bit if necessary. We do this to the copied
@@ -819,12 +812,12 @@ void irlap_send_data_primary_poll(struct
del_timer(&self->poll_timer);

if (self->ack_required) {
- irlap_send_ui_frame(self, skb, self->caddr, CMD_FRAME);
+ irlap_send_ui_frame(self, skb_get(skb), self->caddr, CMD_FRAME);
irlap_send_rr_frame(self, CMD_FRAME);
self->ack_required = FALSE;
} else {
skb->data[1] |= PF_BIT;
- irlap_send_ui_frame(self, skb, self->caddr, CMD_FRAME);
+ irlap_send_ui_frame(self, skb_get(skb), self->caddr, CMD_FRAME);
}
self->window = self->window_size;
irlap_start_final_timer(self, self->final_timeout);
@@ -857,7 +850,6 @@ void irlap_send_data_secondary_final(str

tx_skb = skb_clone(skb, GFP_ATOMIC);
if (tx_skb == NULL) {
- dev_kfree_skb(skb);
return;
}

@@ -865,7 +857,7 @@ void irlap_send_data_secondary_final(str
skb_set_owner_w(tx_skb, skb->sk);

/* Insert frame in store */
- skb_queue_tail(&self->wx_list, skb);
+ skb_queue_tail(&self->wx_list, skb_get(skb));

tx_skb->data[1] |= PF_BIT;

@@ -878,12 +870,12 @@ void irlap_send_data_secondary_final(str
irlap_send_i_frame(self, tx_skb, RSP_FRAME);
} else {
if (self->ack_required) {
- irlap_send_ui_frame(self, skb, self->caddr, RSP_FRAME);
+ irlap_send_ui_frame(self, skb_get(skb), self->caddr, RSP_FRAME);
irlap_send_rr_frame(self, RSP_FRAME);
self->ack_required = FALSE;
} else {
skb->data[1] |= PF_BIT;
- irlap_send_ui_frame(self, skb, self->caddr, RSP_FRAME);
+ irlap_send_ui_frame(self, skb_get(skb), self->caddr, RSP_FRAME);
}
self->window = self->window_size;

@@ -912,7 +904,6 @@ void irlap_send_data_secondary(struct ir

tx_skb = skb_clone(skb, GFP_ATOMIC);
if (tx_skb == NULL) {
- dev_kfree_skb(skb);
return;
}

@@ -920,7 +911,7 @@ void irlap_send_data_secondary(struct ir
skb_set_owner_w(tx_skb, skb->sk);

/* Insert frame in store */
- skb_queue_tail(&self->wx_list, skb);
+ skb_queue_tail(&self->wx_list, skb_get(skb));

self->vs = (self->vs + 1) % 8;
self->ack_required = FALSE;
@@ -928,7 +919,7 @@ void irlap_send_data_secondary(struct ir

irlap_send_i_frame(self, tx_skb, RSP_FRAME);
} else {
- irlap_send_ui_frame(self, skb, self->caddr, RSP_FRAME);
+ irlap_send_ui_frame(self, skb_get(skb), self->caddr, RSP_FRAME);
self->window -= 1;
}
}
@@ -1023,6 +1014,7 @@ void irlap_resend_rejected_frames(struct
} else {
irlap_send_data_primary_poll(self, skb);
}
+ kfree_skb(skb);
}
}
#endif
@@ -1259,7 +1251,6 @@ static void irlap_recv_test_frame(struct
if (skb->len < sizeof(struct test_frame)) {
IRDA_DEBUG(0, __FUNCTION__
"() test frame to short!\n");
- dev_kfree_skb(skb);
return;
}

@@ -1270,7 +1261,6 @@ static void irlap_recv_test_frame(struct
/* Make sure frame is addressed to us */
if ((info->saddr != self->saddr) &&
(info->saddr != BROADCAST)) {
- dev_kfree_skb(skb);
return;
}
}
@@ -1323,8 +1313,7 @@ int irlap_driver_rcv(struct sk_buff *skb
/* First we check if this frame has a valid connection address */
if ((info.caddr != self->caddr) && (info.caddr != CBROADCAST)) {
IRDA_DEBUG(0, __FUNCTION__ "(), wrong connection address!\n");
- dev_kfree_skb(skb);
- return 0;
+ goto out;
}
/*
* Optimize for the common case and check if the frame is an
@@ -1332,7 +1321,7 @@ int irlap_driver_rcv(struct sk_buff *skb
*/
if (~control & 0x01) {
irlap_recv_i_frame(self, skb, &info, command);
- return 0;
+ goto out;
}
/*
* We now check is the frame is an S(upervisory) frame. Only
@@ -1360,10 +1349,9 @@ int irlap_driver_rcv(struct sk_buff *skb
WARNING(__FUNCTION__
"() Unknown S-frame %02x received!\n",
info.control);
- dev_kfree_skb(skb);
break;
}
- return 0;
+ goto out;
}
/*
* This must be a C(ontrol) frame
@@ -1399,8 +1387,9 @@ int irlap_driver_rcv(struct sk_buff *skb
default:
WARNING(__FUNCTION__ "(), Unknown frame %02x received!\n",
info.control);
- dev_kfree_skb(skb);
break;
}
+out:
+ dev_kfree_skb(skb);
return 0;
}