diff options
author | sjur.brandeland@stericsson.com <sjur.brandeland@stericsson.com> | 2011-05-12 22:44:06 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-05-15 17:45:56 -0400 |
commit | c85c2951d4da1236e32f1858db418221e624aba5 (patch) | |
tree | 8f70d7ab3dbe05ea6f812f9bfb8d341425a29193 /net/caif/cffrml.c | |
parent | bee925db9a77a5736596dcf6f91d0879f5ee915b (diff) |
caif: Handle dev_queue_xmit errors.
Do proper handling of dev_queue_xmit errors in order to
avoid double free of skb and leaks in error conditions.
In cfctrl pending requests are removed when CAIF Link layer goes down.
Signed-off-by: Sjur Brændeland <sjur.brandeland@stericsson.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/caif/cffrml.c')
-rw-r--r-- | net/caif/cffrml.c | 17 |
1 files changed, 15 insertions, 2 deletions
diff --git a/net/caif/cffrml.c b/net/caif/cffrml.c index 4f4f756c49ac..04204b202718 100644 --- a/net/caif/cffrml.c +++ b/net/caif/cffrml.c | |||
@@ -33,7 +33,6 @@ static void cffrml_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl, | |||
33 | static u32 cffrml_rcv_error; | 33 | static u32 cffrml_rcv_error; |
34 | static u32 cffrml_rcv_checsum_error; | 34 | static u32 cffrml_rcv_checsum_error; |
35 | struct cflayer *cffrml_create(u16 phyid, bool use_fcs) | 35 | struct cflayer *cffrml_create(u16 phyid, bool use_fcs) |
36 | |||
37 | { | 36 | { |
38 | struct cffrml *this = kmalloc(sizeof(struct cffrml), GFP_ATOMIC); | 37 | struct cffrml *this = kmalloc(sizeof(struct cffrml), GFP_ATOMIC); |
39 | if (!this) { | 38 | if (!this) { |
@@ -128,6 +127,13 @@ static int cffrml_receive(struct cflayer *layr, struct cfpkt *pkt) | |||
128 | cfpkt_destroy(pkt); | 127 | cfpkt_destroy(pkt); |
129 | return -EPROTO; | 128 | return -EPROTO; |
130 | } | 129 | } |
130 | |||
131 | if (layr->up == NULL) { | ||
132 | pr_err("Layr up is missing!\n"); | ||
133 | cfpkt_destroy(pkt); | ||
134 | return -EINVAL; | ||
135 | } | ||
136 | |||
131 | return layr->up->receive(layr->up, pkt); | 137 | return layr->up->receive(layr->up, pkt); |
132 | } | 138 | } |
133 | 139 | ||
@@ -150,15 +156,22 @@ static int cffrml_transmit(struct cflayer *layr, struct cfpkt *pkt) | |||
150 | cfpkt_info(pkt)->hdr_len += 2; | 156 | cfpkt_info(pkt)->hdr_len += 2; |
151 | if (cfpkt_erroneous(pkt)) { | 157 | if (cfpkt_erroneous(pkt)) { |
152 | pr_err("Packet is erroneous!\n"); | 158 | pr_err("Packet is erroneous!\n"); |
159 | cfpkt_destroy(pkt); | ||
153 | return -EPROTO; | 160 | return -EPROTO; |
154 | } | 161 | } |
162 | |||
163 | if (layr->dn == NULL) { | ||
164 | cfpkt_destroy(pkt); | ||
165 | return -ENODEV; | ||
166 | |||
167 | } | ||
155 | return layr->dn->transmit(layr->dn, pkt); | 168 | return layr->dn->transmit(layr->dn, pkt); |
156 | } | 169 | } |
157 | 170 | ||
158 | static void cffrml_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl, | 171 | static void cffrml_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl, |
159 | int phyid) | 172 | int phyid) |
160 | { | 173 | { |
161 | if (layr->up->ctrlcmd) | 174 | if (layr->up && layr->up->ctrlcmd) |
162 | layr->up->ctrlcmd(layr->up, ctrl, layr->id); | 175 | layr->up->ctrlcmd(layr->up, ctrl, layr->id); |
163 | } | 176 | } |
164 | 177 | ||