diff options
-rw-r--r-- | drivers/isdn/gigaset/capi.c | 83 |
1 files changed, 51 insertions, 32 deletions
diff --git a/drivers/isdn/gigaset/capi.c b/drivers/isdn/gigaset/capi.c index cb55ead557cc..e685123fef48 100644 --- a/drivers/isdn/gigaset/capi.c +++ b/drivers/isdn/gigaset/capi.c | |||
@@ -320,6 +320,39 @@ static const char *format_ie(const char *ie) | |||
320 | return result; | 320 | return result; |
321 | } | 321 | } |
322 | 322 | ||
323 | /* | ||
324 | * emit DATA_B3_CONF message | ||
325 | */ | ||
326 | static void send_data_b3_conf(struct cardstate *cs, struct capi_ctr *ctr, | ||
327 | u16 appl, u16 msgid, int channel, | ||
328 | u16 handle, u16 info) | ||
329 | { | ||
330 | struct sk_buff *cskb; | ||
331 | u8 *msg; | ||
332 | |||
333 | cskb = alloc_skb(CAPI_DATA_B3_CONF_LEN, GFP_ATOMIC); | ||
334 | if (!cskb) { | ||
335 | dev_err(cs->dev, "%s: out of memory\n", __func__); | ||
336 | return; | ||
337 | } | ||
338 | /* frequent message, avoid _cmsg overhead */ | ||
339 | msg = __skb_put(cskb, CAPI_DATA_B3_CONF_LEN); | ||
340 | CAPIMSG_SETLEN(msg, CAPI_DATA_B3_CONF_LEN); | ||
341 | CAPIMSG_SETAPPID(msg, appl); | ||
342 | CAPIMSG_SETCOMMAND(msg, CAPI_DATA_B3); | ||
343 | CAPIMSG_SETSUBCOMMAND(msg, CAPI_CONF); | ||
344 | CAPIMSG_SETMSGID(msg, msgid); | ||
345 | CAPIMSG_SETCONTROLLER(msg, ctr->cnr); | ||
346 | CAPIMSG_SETPLCI_PART(msg, channel); | ||
347 | CAPIMSG_SETNCCI_PART(msg, 1); | ||
348 | CAPIMSG_SETHANDLE_CONF(msg, handle); | ||
349 | CAPIMSG_SETINFO_CONF(msg, info); | ||
350 | |||
351 | /* emit message */ | ||
352 | dump_rawmsg(DEBUG_MCMD, __func__, msg); | ||
353 | capi_ctr_handle_message(ctr, appl, cskb); | ||
354 | } | ||
355 | |||
323 | 356 | ||
324 | /* | 357 | /* |
325 | * driver interface functions | 358 | * driver interface functions |
@@ -340,7 +373,6 @@ void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *dskb) | |||
340 | struct gigaset_capi_ctr *iif = cs->iif; | 373 | struct gigaset_capi_ctr *iif = cs->iif; |
341 | struct gigaset_capi_appl *ap = bcs->ap; | 374 | struct gigaset_capi_appl *ap = bcs->ap; |
342 | unsigned char *req = skb_mac_header(dskb); | 375 | unsigned char *req = skb_mac_header(dskb); |
343 | struct sk_buff *cskb; | ||
344 | u16 flags; | 376 | u16 flags; |
345 | 377 | ||
346 | /* update statistics */ | 378 | /* update statistics */ |
@@ -357,34 +389,17 @@ void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *dskb) | |||
357 | return; | 389 | return; |
358 | } | 390 | } |
359 | 391 | ||
360 | /* ToDo: honor unset "delivery confirmation" bit */ | 392 | /* |
393 | * send DATA_B3_CONF if "delivery confirmation" bit was set in request; | ||
394 | * otherwise it has already been sent by do_data_b3_req() | ||
395 | */ | ||
361 | flags = CAPIMSG_FLAGS(req); | 396 | flags = CAPIMSG_FLAGS(req); |
362 | 397 | if (flags & CAPI_FLAGS_DELIVERY_CONFIRMATION) | |
363 | /* build DATA_B3_CONF message */ | 398 | send_data_b3_conf(cs, &iif->ctr, ap->id, CAPIMSG_MSGID(req), |
364 | cskb = alloc_skb(CAPI_DATA_B3_CONF_LEN, GFP_ATOMIC); | 399 | bcs->channel + 1, CAPIMSG_HANDLE_REQ(req), |
365 | if (!cskb) { | 400 | (flags & ~CAPI_FLAGS_DELIVERY_CONFIRMATION) ? |
366 | dev_err(cs->dev, "%s: out of memory\n", __func__); | 401 | CapiFlagsNotSupportedByProtocol : |
367 | return; | 402 | CAPI_NOERROR); |
368 | } | ||
369 | /* frequent message, avoid _cmsg overhead */ | ||
370 | CAPIMSG_SETLEN(cskb->data, CAPI_DATA_B3_CONF_LEN); | ||
371 | CAPIMSG_SETAPPID(cskb->data, ap->id); | ||
372 | CAPIMSG_SETCOMMAND(cskb->data, CAPI_DATA_B3); | ||
373 | CAPIMSG_SETSUBCOMMAND(cskb->data, CAPI_CONF); | ||
374 | CAPIMSG_SETMSGID(cskb->data, CAPIMSG_MSGID(req)); | ||
375 | CAPIMSG_SETCONTROLLER(cskb->data, iif->ctr.cnr); | ||
376 | CAPIMSG_SETPLCI_PART(cskb->data, bcs->channel + 1); | ||
377 | CAPIMSG_SETNCCI_PART(cskb->data, 1); | ||
378 | CAPIMSG_SETHANDLE_CONF(cskb->data, CAPIMSG_HANDLE_REQ(req)); | ||
379 | if (flags & ~CAPI_FLAGS_DELIVERY_CONFIRMATION) | ||
380 | CAPIMSG_SETINFO_CONF(cskb->data, | ||
381 | CapiFlagsNotSupportedByProtocol); | ||
382 | else | ||
383 | CAPIMSG_SETINFO_CONF(cskb->data, CAPI_NOERROR); | ||
384 | |||
385 | /* emit message */ | ||
386 | dump_rawmsg(DEBUG_LLDATA, "DATA_B3_CONF", cskb->data); | ||
387 | capi_ctr_handle_message(&iif->ctr, ap->id, cskb); | ||
388 | } | 403 | } |
389 | EXPORT_SYMBOL_GPL(gigaset_skb_sent); | 404 | EXPORT_SYMBOL_GPL(gigaset_skb_sent); |
390 | 405 | ||
@@ -1795,6 +1810,8 @@ static void do_data_b3_req(struct gigaset_capi_ctr *iif, | |||
1795 | u16 msglen = CAPIMSG_LEN(skb->data); | 1810 | u16 msglen = CAPIMSG_LEN(skb->data); |
1796 | u16 datalen = CAPIMSG_DATALEN(skb->data); | 1811 | u16 datalen = CAPIMSG_DATALEN(skb->data); |
1797 | u16 flags = CAPIMSG_FLAGS(skb->data); | 1812 | u16 flags = CAPIMSG_FLAGS(skb->data); |
1813 | u16 msgid = CAPIMSG_MSGID(skb->data); | ||
1814 | u16 handle = CAPIMSG_HANDLE_REQ(skb->data); | ||
1798 | 1815 | ||
1799 | /* frequent message, avoid _cmsg overhead */ | 1816 | /* frequent message, avoid _cmsg overhead */ |
1800 | dump_rawmsg(DEBUG_LLDATA, "DATA_B3_REQ", skb->data); | 1817 | dump_rawmsg(DEBUG_LLDATA, "DATA_B3_REQ", skb->data); |
@@ -1845,12 +1862,14 @@ static void do_data_b3_req(struct gigaset_capi_ctr *iif, | |||
1845 | return; | 1862 | return; |
1846 | } | 1863 | } |
1847 | 1864 | ||
1848 | /* DATA_B3_CONF reply will be sent by gigaset_skb_sent() */ | ||
1849 | |||
1850 | /* | 1865 | /* |
1851 | * ToDo: honor unset "delivery confirmation" bit | 1866 | * DATA_B3_CONF will be sent by gigaset_skb_sent() only if "delivery |
1852 | * (send DATA_B3_CONF immediately?) | 1867 | * confirmation" bit is set; otherwise we have to send it now |
1853 | */ | 1868 | */ |
1869 | if (!(flags & CAPI_FLAGS_DELIVERY_CONFIRMATION)) | ||
1870 | send_data_b3_conf(cs, &iif->ctr, ap->id, msgid, channel, handle, | ||
1871 | flags ? CapiFlagsNotSupportedByProtocol | ||
1872 | : CAPI_NOERROR); | ||
1854 | } | 1873 | } |
1855 | 1874 | ||
1856 | /* | 1875 | /* |