aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorSjur Brændeland <sjur.brandeland@stericsson.com>2011-04-11 06:43:51 -0400
committerDavid S. Miller <davem@davemloft.net>2011-04-11 18:08:48 -0400
commit4dd820c088d201e526840c9dbc2f0b87a0a41868 (patch)
treefac7a3a70bd32df3104ae6f1273a727fb0fa006f /net
parent73d6ac633c6c0ca703f90db0b808d9593e46aef6 (diff)
caif: Don't resend if dev_queue_xmit fails.
If CAIF Link Layer returns an error, we no longer try to re-build the CAIF packet and resend it. Instead, we simply return any transmission errors to the socket client. Signed-off-by: Sjur Brændeland <sjur.brandeland@stericsson.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/caif/caif_dev.c21
-rw-r--r--net/caif/caif_socket.c35
-rw-r--r--net/caif/cfdgml.c7
-rw-r--r--net/caif/cffrml.c8
-rw-r--r--net/caif/cfmuxl.c7
-rw-r--r--net/caif/cfserl.c7
-rw-r--r--net/caif/cfutill.c7
-rw-r--r--net/caif/cfveil.c5
-rw-r--r--net/caif/cfvidl.c5
9 files changed, 14 insertions, 88 deletions
diff --git a/net/caif/caif_dev.c b/net/caif/caif_dev.c
index b533bb09a002..a518fdd4da0a 100644
--- a/net/caif/caif_dev.c
+++ b/net/caif/caif_dev.c
@@ -120,25 +120,12 @@ static int transmit(struct cflayer *layer, struct cfpkt *pkt)
120{ 120{
121 struct caif_device_entry *caifd = 121 struct caif_device_entry *caifd =
122 container_of(layer, struct caif_device_entry, layer); 122 container_of(layer, struct caif_device_entry, layer);
123 struct sk_buff *skb, *skb2; 123 struct sk_buff *skb;
124 int ret = -EINVAL; 124
125 skb = cfpkt_tonative(pkt); 125 skb = cfpkt_tonative(pkt);
126 skb->dev = caifd->netdev; 126 skb->dev = caifd->netdev;
127 /* 127
128 * Don't allow SKB to be destroyed upon error, but signal resend 128 dev_queue_xmit(skb);
129 * notification to clients. We can't rely on the return value as
130 * congestion (NET_XMIT_CN) sometimes drops the packet, sometimes don't.
131 */
132 if (netif_queue_stopped(caifd->netdev))
133 return -EAGAIN;
134 skb2 = skb_get(skb);
135
136 ret = dev_queue_xmit(skb2);
137
138 if (!ret)
139 kfree_skb(skb);
140 else
141 return -EAGAIN;
142 129
143 return 0; 130 return 0;
144} 131}
diff --git a/net/caif/caif_socket.c b/net/caif/caif_socket.c
index 37a4034dfc29..20212424e2e8 100644
--- a/net/caif/caif_socket.c
+++ b/net/caif/caif_socket.c
@@ -519,43 +519,14 @@ static int transmit_skb(struct sk_buff *skb, struct caifsock *cf_sk,
519 int noblock, long timeo) 519 int noblock, long timeo)
520{ 520{
521 struct cfpkt *pkt; 521 struct cfpkt *pkt;
522 int ret, loopcnt = 0;
523 522
524 pkt = cfpkt_fromnative(CAIF_DIR_OUT, skb); 523 pkt = cfpkt_fromnative(CAIF_DIR_OUT, skb);
525 memset(cfpkt_info(pkt), 0, sizeof(struct caif_payload_info)); 524 memset(cfpkt_info(pkt), 0, sizeof(struct caif_payload_info));
526 do {
527
528 ret = -ETIMEDOUT;
529 525
530 /* Slight paranoia, probably not needed. */ 526 if (cf_sk->layer.dn == NULL)
531 if (unlikely(loopcnt++ > 1000)) { 527 return -EINVAL;
532 pr_warn("transmit retries failed, error = %d\n", ret);
533 break;
534 }
535 528
536 if (cf_sk->layer.dn != NULL) 529 return cf_sk->layer.dn->transmit(cf_sk->layer.dn, pkt);
537 ret = cf_sk->layer.dn->transmit(cf_sk->layer.dn, pkt);
538 if (likely(ret >= 0))
539 break;
540 /* if transmit return -EAGAIN, then retry */
541 if (noblock && ret == -EAGAIN)
542 break;
543 timeo = caif_wait_for_flow_on(cf_sk, 0, timeo, &ret);
544 if (signal_pending(current)) {
545 ret = sock_intr_errno(timeo);
546 break;
547 }
548 if (ret)
549 break;
550 if (cf_sk->sk.sk_state != CAIF_CONNECTED ||
551 sock_flag(&cf_sk->sk, SOCK_DEAD) ||
552 (cf_sk->sk.sk_shutdown & RCV_SHUTDOWN)) {
553 ret = -EPIPE;
554 cf_sk->sk.sk_err = EPIPE;
555 break;
556 }
557 } while (ret == -EAGAIN);
558 return ret;
559} 530}
560 531
561/* Copied from af_unix:unix_dgram_sendmsg, and adapted to CAIF */ 532/* Copied from af_unix:unix_dgram_sendmsg, and adapted to CAIF */
diff --git a/net/caif/cfdgml.c b/net/caif/cfdgml.c
index 054fdb5aeb88..0382dec84fdc 100644
--- a/net/caif/cfdgml.c
+++ b/net/caif/cfdgml.c
@@ -108,10 +108,5 @@ static int cfdgml_transmit(struct cflayer *layr, struct cfpkt *pkt)
108 */ 108 */
109 info->hdr_len = 4; 109 info->hdr_len = 4;
110 info->dev_info = &service->dev_info; 110 info->dev_info = &service->dev_info;
111 ret = layr->dn->transmit(layr->dn, pkt); 111 return layr->dn->transmit(layr->dn, pkt);
112 if (ret < 0) {
113 u32 tmp32;
114 cfpkt_extr_head(pkt, &tmp32, 4);
115 }
116 return ret;
117} 112}
diff --git a/net/caif/cffrml.c b/net/caif/cffrml.c
index a445043931ae..2423fed8e26c 100644
--- a/net/caif/cffrml.c
+++ b/net/caif/cffrml.c
@@ -120,7 +120,6 @@ static int cffrml_transmit(struct cflayer *layr, struct cfpkt *pkt)
120 int tmp; 120 int tmp;
121 u16 chks; 121 u16 chks;
122 u16 len; 122 u16 len;
123 int ret;
124 struct cffrml *this = container_obj(layr); 123 struct cffrml *this = container_obj(layr);
125 if (this->dofcs) { 124 if (this->dofcs) {
126 chks = cfpkt_iterate(pkt, cffrml_checksum, 0xffff); 125 chks = cfpkt_iterate(pkt, cffrml_checksum, 0xffff);
@@ -137,12 +136,7 @@ static int cffrml_transmit(struct cflayer *layr, struct cfpkt *pkt)
137 pr_err("Packet is erroneous!\n"); 136 pr_err("Packet is erroneous!\n");
138 return -EPROTO; 137 return -EPROTO;
139 } 138 }
140 ret = layr->dn->transmit(layr->dn, pkt); 139 return layr->dn->transmit(layr->dn, pkt);
141 if (ret < 0) {
142 /* Remove header on faulty packet. */
143 cfpkt_extr_head(pkt, &tmp, 2);
144 }
145 return ret;
146} 140}
147 141
148static void cffrml_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl, 142static void cffrml_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl,
diff --git a/net/caif/cfmuxl.c b/net/caif/cfmuxl.c
index f8ce0f3d9210..ebfda2c9290b 100644
--- a/net/caif/cfmuxl.c
+++ b/net/caif/cfmuxl.c
@@ -184,7 +184,6 @@ static int cfmuxl_receive(struct cflayer *layr, struct cfpkt *pkt)
184 184
185static int cfmuxl_transmit(struct cflayer *layr, struct cfpkt *pkt) 185static int cfmuxl_transmit(struct cflayer *layr, struct cfpkt *pkt)
186{ 186{
187 int ret;
188 struct cfmuxl *muxl = container_obj(layr); 187 struct cfmuxl *muxl = container_obj(layr);
189 u8 linkid; 188 u8 linkid;
190 struct cflayer *dn; 189 struct cflayer *dn;
@@ -198,11 +197,7 @@ static int cfmuxl_transmit(struct cflayer *layr, struct cfpkt *pkt)
198 info->hdr_len += 1; 197 info->hdr_len += 1;
199 linkid = info->channel_id; 198 linkid = info->channel_id;
200 cfpkt_add_head(pkt, &linkid, 1); 199 cfpkt_add_head(pkt, &linkid, 1);
201 ret = dn->transmit(dn, pkt); 200 return dn->transmit(dn, pkt);
202 /* Remove MUX protocol header upon error. */
203 if (ret < 0)
204 cfpkt_extr_head(pkt, &linkid, 1);
205 return ret;
206} 201}
207 202
208static void cfmuxl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl, 203static void cfmuxl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl,
diff --git a/net/caif/cfserl.c b/net/caif/cfserl.c
index 8303fe3ebf89..2715c84cfa87 100644
--- a/net/caif/cfserl.c
+++ b/net/caif/cfserl.c
@@ -179,15 +179,10 @@ static int cfserl_receive(struct cflayer *l, struct cfpkt *newpkt)
179static int cfserl_transmit(struct cflayer *layer, struct cfpkt *newpkt) 179static int cfserl_transmit(struct cflayer *layer, struct cfpkt *newpkt)
180{ 180{
181 struct cfserl *layr = container_obj(layer); 181 struct cfserl *layr = container_obj(layer);
182 int ret;
183 u8 tmp8 = CFSERL_STX; 182 u8 tmp8 = CFSERL_STX;
184 if (layr->usestx) 183 if (layr->usestx)
185 cfpkt_add_head(newpkt, &tmp8, 1); 184 cfpkt_add_head(newpkt, &tmp8, 1);
186 ret = layer->dn->transmit(layer->dn, newpkt); 185 return layer->dn->transmit(layer->dn, newpkt);
187 if (ret < 0)
188 cfpkt_extr_head(newpkt, &tmp8, 1);
189
190 return ret;
191} 186}
192 187
193static void cfserl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl, 188static void cfserl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl,
diff --git a/net/caif/cfutill.c b/net/caif/cfutill.c
index 315c0d601368..98e027db18ed 100644
--- a/net/caif/cfutill.c
+++ b/net/caif/cfutill.c
@@ -100,10 +100,5 @@ static int cfutill_transmit(struct cflayer *layr, struct cfpkt *pkt)
100 */ 100 */
101 info->hdr_len = 1; 101 info->hdr_len = 1;
102 info->dev_info = &service->dev_info; 102 info->dev_info = &service->dev_info;
103 ret = layr->dn->transmit(layr->dn, pkt); 103 return layr->dn->transmit(layr->dn, pkt);
104 if (ret < 0) {
105 u32 tmp32;
106 cfpkt_extr_head(pkt, &tmp32, 4);
107 }
108 return ret;
109} 104}
diff --git a/net/caif/cfveil.c b/net/caif/cfveil.c
index c3b1dec4acf6..1a588cd818ea 100644
--- a/net/caif/cfveil.c
+++ b/net/caif/cfveil.c
@@ -96,8 +96,5 @@ static int cfvei_transmit(struct cflayer *layr, struct cfpkt *pkt)
96 info->channel_id = service->layer.id; 96 info->channel_id = service->layer.id;
97 info->hdr_len = 1; 97 info->hdr_len = 1;
98 info->dev_info = &service->dev_info; 98 info->dev_info = &service->dev_info;
99 ret = layr->dn->transmit(layr->dn, pkt); 99 return layr->dn->transmit(layr->dn, pkt);
100 if (ret < 0)
101 cfpkt_extr_head(pkt, &tmp, 1);
102 return ret;
103} 100}
diff --git a/net/caif/cfvidl.c b/net/caif/cfvidl.c
index bf6fef2a0eff..b2f5989ad455 100644
--- a/net/caif/cfvidl.c
+++ b/net/caif/cfvidl.c
@@ -60,8 +60,5 @@ static int cfvidl_transmit(struct cflayer *layr, struct cfpkt *pkt)
60 info = cfpkt_info(pkt); 60 info = cfpkt_info(pkt);
61 info->channel_id = service->layer.id; 61 info->channel_id = service->layer.id;
62 info->dev_info = &service->dev_info; 62 info->dev_info = &service->dev_info;
63 ret = layr->dn->transmit(layr->dn, pkt); 63 return layr->dn->transmit(layr->dn, pkt);
64 if (ret < 0)
65 cfpkt_extr_head(pkt, &videoheader, 4);
66 return ret;
67} 64}