aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/isdn
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-04-15 12:00:47 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-04-15 12:00:47 -0400
commit6c373ca89399c5a3f7ef210ad8f63dc3437da345 (patch)
tree74d1ec65087df1da1021b43ac51acc1ee8601809 /drivers/isdn
parentbb0fd7ab0986105765d11baa82e619c618a235aa (diff)
parent9f9151412dd7aae0e3f51a89ae4a1f8755fdb4d0 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
Pull networking updates from David Miller: 1) Add BQL support to via-rhine, from Tino Reichardt. 2) Integrate SWITCHDEV layer support into the DSA layer, so DSA drivers can support hw switch offloading. From Floria Fainelli. 3) Allow 'ip address' commands to initiate multicast group join/leave, from Madhu Challa. 4) Many ipv4 FIB lookup optimizations from Alexander Duyck. 5) Support EBPF in cls_bpf classifier and act_bpf action, from Daniel Borkmann. 6) Remove the ugly compat support in ARP for ugly layers like ax25, rose, etc. And use this to clean up the neigh layer, then use it to implement MPLS support. All from Eric Biederman. 7) Support L3 forwarding offloading in switches, from Scott Feldman. 8) Collapse the LOCAL and MAIN ipv4 FIB tables when possible, to speed up route lookups even further. From Alexander Duyck. 9) Many improvements and bug fixes to the rhashtable implementation, from Herbert Xu and Thomas Graf. In particular, in the case where an rhashtable user bulk adds a large number of items into an empty table, we expand the table much more sanely. 10) Don't make the tcp_metrics hash table per-namespace, from Eric Biederman. 11) Extend EBPF to access SKB fields, from Alexei Starovoitov. 12) Split out new connection request sockets so that they can be established in the main hash table. Much less false sharing since hash lookups go direct to the request sockets instead of having to go first to the listener then to the request socks hashed underneath. From Eric Dumazet. 13) Add async I/O support for crytpo AF_ALG sockets, from Tadeusz Struk. 14) Support stable privacy address generation for RFC7217 in IPV6. From Hannes Frederic Sowa. 15) Hash network namespace into IP frag IDs, also from Hannes Frederic Sowa. 16) Convert PTP get/set methods to use 64-bit time, from Richard Cochran. * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next: (1816 commits) fm10k: Bump driver version to 0.15.2 fm10k: corrected VF multicast update fm10k: mbx_update_max_size does not drop all oversized messages fm10k: reset head instead of calling update_max_size fm10k: renamed mbx_tx_dropped to mbx_tx_oversized fm10k: update xcast mode before synchronizing multicast addresses fm10k: start service timer on probe fm10k: fix function header comment fm10k: comment next_vf_mbx flow fm10k: don't handle mailbox events in iov_event path and always process mailbox fm10k: use separate workqueue for fm10k driver fm10k: Set PF queues to unlimited bandwidth during virtualization fm10k: expose tx_timeout_count as an ethtool stat fm10k: only increment tx_timeout_count in Tx hang path fm10k: remove extraneous "Reset interface" message fm10k: separate PF only stats so that VF does not display them fm10k: use hw->mac.max_queues for stats fm10k: only show actual queues, not the maximum in hardware fm10k: allow creation of VLAN on default vid fm10k: fix unused warnings ...
Diffstat (limited to 'drivers/isdn')
-rw-r--r--drivers/isdn/gigaset/ev-layer.c365
-rw-r--r--drivers/isdn/i4l/isdn_net.c33
-rw-r--r--drivers/isdn/mISDN/socket.c7
3 files changed, 198 insertions, 207 deletions
diff --git a/drivers/isdn/gigaset/ev-layer.c b/drivers/isdn/gigaset/ev-layer.c
index c8ced12fa452..1cfcea62aed9 100644
--- a/drivers/isdn/gigaset/ev-layer.c
+++ b/drivers/isdn/gigaset/ev-layer.c
@@ -389,22 +389,49 @@ zsau_resp[] =
389 {NULL, ZSAU_UNKNOWN} 389 {NULL, ZSAU_UNKNOWN}
390}; 390};
391 391
392/* retrieve CID from parsed response 392/* check for and remove fixed string prefix
393 * returns 0 if no CID, -1 if invalid CID, or CID value 1..65535 393 * If s starts with prefix terminated by a non-alphanumeric character,
394 * return pointer to the first character after that, otherwise return NULL.
394 */ 395 */
395static int cid_of_response(char *s) 396static char *skip_prefix(char *s, const char *prefix)
396{ 397{
397 int cid; 398 while (*prefix)
398 int rc; 399 if (*s++ != *prefix++)
399 400 return NULL;
400 if (s[-1] != ';') 401 if (isalnum(*s))
401 return 0; /* no CID separator */ 402 return NULL;
402 rc = kstrtoint(s, 10, &cid); 403 return s;
403 if (rc) 404}
404 return 0; /* CID not numeric */ 405
405 if (cid < 1 || cid > 65535) 406/* queue event with CID */
406 return -1; /* CID out of range */ 407static void add_cid_event(struct cardstate *cs, int cid, int type,
407 return cid; 408 void *ptr, int parameter)
409{
410 unsigned long flags;
411 unsigned next, tail;
412 struct event_t *event;
413
414 gig_dbg(DEBUG_EVENT, "queueing event %d for cid %d", type, cid);
415
416 spin_lock_irqsave(&cs->ev_lock, flags);
417
418 tail = cs->ev_tail;
419 next = (tail + 1) % MAX_EVENTS;
420 if (unlikely(next == cs->ev_head)) {
421 dev_err(cs->dev, "event queue full\n");
422 kfree(ptr);
423 } else {
424 event = cs->events + tail;
425 event->type = type;
426 event->cid = cid;
427 event->ptr = ptr;
428 event->arg = NULL;
429 event->parameter = parameter;
430 event->at_state = NULL;
431 cs->ev_tail = next;
432 }
433
434 spin_unlock_irqrestore(&cs->ev_lock, flags);
408} 435}
409 436
410/** 437/**
@@ -417,190 +444,188 @@ static int cid_of_response(char *s)
417 */ 444 */
418void gigaset_handle_modem_response(struct cardstate *cs) 445void gigaset_handle_modem_response(struct cardstate *cs)
419{ 446{
420 unsigned char *argv[MAX_REC_PARAMS + 1]; 447 char *eoc, *psep, *ptr;
421 int params;
422 int i, j;
423 const struct resp_type_t *rt; 448 const struct resp_type_t *rt;
424 const struct zsau_resp_t *zr; 449 const struct zsau_resp_t *zr;
425 int curarg; 450 int cid, parameter;
426 unsigned long flags; 451 u8 type, value;
427 unsigned next, tail, head; 452
428 struct event_t *event; 453 if (!cs->cbytes) {
429 int resp_code;
430 int param_type;
431 int abort;
432 size_t len;
433 int cid;
434 int rawstring;
435
436 len = cs->cbytes;
437 if (!len) {
438 /* ignore additional LFs/CRs (M10x config mode or cx100) */ 454 /* ignore additional LFs/CRs (M10x config mode or cx100) */
439 gig_dbg(DEBUG_MCMD, "skipped EOL [%02X]", cs->respdata[0]); 455 gig_dbg(DEBUG_MCMD, "skipped EOL [%02X]", cs->respdata[0]);
440 return; 456 return;
441 } 457 }
442 cs->respdata[len] = 0; 458 cs->respdata[cs->cbytes] = 0;
443 argv[0] = cs->respdata; 459
444 params = 1;
445 if (cs->at_state.getstring) { 460 if (cs->at_state.getstring) {
446 /* getstring only allowed without cid at the moment */ 461 /* state machine wants next line verbatim */
447 cs->at_state.getstring = 0; 462 cs->at_state.getstring = 0;
448 rawstring = 1; 463 ptr = kstrdup(cs->respdata, GFP_ATOMIC);
449 cid = 0; 464 gig_dbg(DEBUG_EVENT, "string==%s", ptr ? ptr : "NULL");
450 } else { 465 add_cid_event(cs, 0, RSP_STRING, ptr, 0);
451 /* parse line */ 466 return;
452 for (i = 0; i < len; i++) 467 }
453 switch (cs->respdata[i]) {
454 case ';':
455 case ',':
456 case '=':
457 if (params > MAX_REC_PARAMS) {
458 dev_warn(cs->dev,
459 "too many parameters in response\n");
460 /* need last parameter (might be CID) */
461 params--;
462 }
463 argv[params++] = cs->respdata + i + 1;
464 }
465
466 rawstring = 0;
467 cid = params > 1 ? cid_of_response(argv[params - 1]) : 0;
468 if (cid < 0) {
469 gigaset_add_event(cs, &cs->at_state, RSP_INVAL,
470 NULL, 0, NULL);
471 return;
472 }
473 468
474 for (j = 1; j < params; ++j) 469 /* look up response type */
475 argv[j][-1] = 0; 470 for (rt = resp_type; rt->response; ++rt) {
471 eoc = skip_prefix(cs->respdata, rt->response);
472 if (eoc)
473 break;
474 }
475 if (!rt->response) {
476 add_cid_event(cs, 0, RSP_NONE, NULL, 0);
477 gig_dbg(DEBUG_EVENT, "unknown modem response: '%s'\n",
478 cs->respdata);
479 return;
480 }
476 481
477 gig_dbg(DEBUG_EVENT, "CMD received: %s", argv[0]); 482 /* check for CID */
478 if (cid) { 483 psep = strrchr(cs->respdata, ';');
479 --params; 484 if (psep &&
480 gig_dbg(DEBUG_EVENT, "CID: %s", argv[params]); 485 !kstrtoint(psep + 1, 10, &cid) &&
481 } 486 cid >= 1 && cid <= 65535) {
482 gig_dbg(DEBUG_EVENT, "available params: %d", params - 1); 487 /* valid CID: chop it off */
483 for (j = 1; j < params; j++) 488 *psep = 0;
484 gig_dbg(DEBUG_EVENT, "param %d: %s", j, argv[j]); 489 } else {
490 /* no valid CID: leave unchanged */
491 cid = 0;
485 } 492 }
486 493
487 spin_lock_irqsave(&cs->ev_lock, flags); 494 gig_dbg(DEBUG_EVENT, "CMD received: %s", cs->respdata);
488 head = cs->ev_head; 495 if (cid)
489 tail = cs->ev_tail; 496 gig_dbg(DEBUG_EVENT, "CID: %d", cid);
490 497
491 abort = 1; 498 switch (rt->type) {
492 curarg = 0; 499 case RT_NOTHING:
493 while (curarg < params) { 500 /* check parameter separator */
494 next = (tail + 1) % MAX_EVENTS; 501 if (*eoc)
495 if (unlikely(next == head)) { 502 goto bad_param; /* extra parameter */
496 dev_err(cs->dev, "event queue full\n");
497 break;
498 }
499 503
500 event = cs->events + tail; 504 add_cid_event(cs, cid, rt->resp_code, NULL, 0);
501 event->at_state = NULL; 505 break;
502 event->cid = cid;
503 event->ptr = NULL;
504 event->arg = NULL;
505 tail = next;
506 506
507 if (rawstring) { 507 case RT_RING:
508 resp_code = RSP_STRING; 508 /* check parameter separator */
509 param_type = RT_STRING; 509 if (!*eoc)
510 } else { 510 eoc = NULL; /* no parameter */
511 for (rt = resp_type; rt->response; ++rt) 511 else if (*eoc++ != ',')
512 if (!strcmp(argv[curarg], rt->response)) 512 goto bad_param;
513
514 add_cid_event(cs, 0, rt->resp_code, NULL, cid);
515
516 /* process parameters as individual responses */
517 while (eoc) {
518 /* look up parameter type */
519 psep = NULL;
520 for (rt = resp_type; rt->response; ++rt) {
521 psep = skip_prefix(eoc, rt->response);
522 if (psep)
513 break; 523 break;
524 }
514 525
515 if (!rt->response) { 526 /* all legal parameters are of type RT_STRING */
516 event->type = RSP_NONE; 527 if (!psep || rt->type != RT_STRING) {
517 gig_dbg(DEBUG_EVENT, 528 dev_warn(cs->dev,
518 "unknown modem response: '%s'\n", 529 "illegal RING parameter: '%s'\n",
519 argv[curarg]); 530 eoc);
520 break; 531 return;
521 } 532 }
522 533
523 resp_code = rt->resp_code; 534 /* skip parameter value separator */
524 param_type = rt->type; 535 if (*psep++ != '=')
525 ++curarg; 536 goto bad_param;
526 }
527 537
528 event->type = resp_code; 538 /* look up end of parameter */
539 eoc = strchr(psep, ',');
540 if (eoc)
541 *eoc++ = 0;
529 542
530 switch (param_type) { 543 /* retrieve parameter value */
531 case RT_NOTHING: 544 ptr = kstrdup(psep, GFP_ATOMIC);
532 break; 545
533 case RT_RING: 546 /* queue event */
534 if (!cid) { 547 add_cid_event(cs, cid, rt->resp_code, ptr, 0);
535 dev_err(cs->dev, 548 }
536 "received RING without CID!\n"); 549 break;
537 event->type = RSP_INVAL; 550
538 abort = 1; 551 case RT_ZSAU:
539 } else { 552 /* check parameter separator */
540 event->cid = 0; 553 if (!*eoc) {
541 event->parameter = cid; 554 /* no parameter */
542 abort = 0; 555 add_cid_event(cs, cid, rt->resp_code, NULL, ZSAU_NONE);
543 }
544 break; 556 break;
545 case RT_ZSAU: 557 }
546 if (curarg >= params) { 558 if (*eoc++ != '=')
547 event->parameter = ZSAU_NONE; 559 goto bad_param;
560
561 /* look up parameter value */
562 for (zr = zsau_resp; zr->str; ++zr)
563 if (!strcmp(eoc, zr->str))
548 break; 564 break;
549 } 565 if (!zr->str)
550 for (zr = zsau_resp; zr->str; ++zr) 566 goto bad_param;
551 if (!strcmp(argv[curarg], zr->str)) 567
552 break; 568 add_cid_event(cs, cid, rt->resp_code, NULL, zr->code);
553 event->parameter = zr->code; 569 break;
554 if (!zr->str) 570
555 dev_warn(cs->dev, 571 case RT_STRING:
556 "%s: unknown parameter %s after ZSAU\n", 572 /* check parameter separator */
557 __func__, argv[curarg]); 573 if (*eoc++ != '=')
558 ++curarg; 574 goto bad_param;
559 break; 575
560 case RT_STRING: 576 /* retrieve parameter value */
561 if (curarg < params) { 577 ptr = kstrdup(eoc, GFP_ATOMIC);
562 event->ptr = kstrdup(argv[curarg], GFP_ATOMIC); 578
563 if (!event->ptr) 579 /* queue event */
564 dev_err(cs->dev, "out of memory\n"); 580 add_cid_event(cs, cid, rt->resp_code, ptr, 0);
565 ++curarg; 581 break;
566 } 582
567 gig_dbg(DEBUG_EVENT, "string==%s", 583 case RT_ZCAU:
568 event->ptr ? (char *) event->ptr : "NULL"); 584 /* check parameter separators */
569 break; 585 if (*eoc++ != '=')
570 case RT_ZCAU: 586 goto bad_param;
571 event->parameter = -1; 587 psep = strchr(eoc, ',');
572 if (curarg + 1 < params) { 588 if (!psep)
573 u8 type, value; 589 goto bad_param;
574 590 *psep++ = 0;
575 i = kstrtou8(argv[curarg++], 16, &type); 591
576 j = kstrtou8(argv[curarg++], 16, &value); 592 /* decode parameter values */
577 if (i == 0 && j == 0) 593 if (kstrtou8(eoc, 16, &type) || kstrtou8(psep, 16, &value)) {
578 event->parameter = (type << 8) | value; 594 *--psep = ',';
579 } else 595 goto bad_param;
580 curarg = params - 1;
581 break;
582 case RT_NUMBER:
583 if (curarg >= params ||
584 kstrtoint(argv[curarg++], 10, &event->parameter))
585 event->parameter = -1;
586 gig_dbg(DEBUG_EVENT, "parameter==%d", event->parameter);
587 break;
588 } 596 }
597 parameter = (type << 8) | value;
589 598
590 if (resp_code == RSP_ZDLE) 599 add_cid_event(cs, cid, rt->resp_code, NULL, parameter);
591 cs->dle = event->parameter; 600 break;
592 601
593 if (abort) 602 case RT_NUMBER:
594 break; 603 /* check parameter separator */
595 } 604 if (*eoc++ != '=')
605 goto bad_param;
596 606
597 cs->ev_tail = tail; 607 /* decode parameter value */
598 spin_unlock_irqrestore(&cs->ev_lock, flags); 608 if (kstrtoint(eoc, 10, &parameter))
609 goto bad_param;
610
611 /* special case ZDLE: set flag before queueing event */
612 if (rt->resp_code == RSP_ZDLE)
613 cs->dle = parameter;
599 614
600 if (curarg != params) 615 add_cid_event(cs, cid, rt->resp_code, NULL, parameter);
601 gig_dbg(DEBUG_EVENT, 616 break;
602 "invalid number of processed parameters: %d/%d", 617
603 curarg, params); 618bad_param:
619 /* parameter unexpected, incomplete or malformed */
620 dev_warn(cs->dev, "bad parameter in response '%s'\n",
621 cs->respdata);
622 add_cid_event(cs, cid, rt->resp_code, NULL, -1);
623 break;
624
625 default:
626 dev_err(cs->dev, "%s: internal error on '%s'\n",
627 __func__, cs->respdata);
628 }
604} 629}
605EXPORT_SYMBOL_GPL(gigaset_handle_modem_response); 630EXPORT_SYMBOL_GPL(gigaset_handle_modem_response);
606 631
diff --git a/drivers/isdn/i4l/isdn_net.c b/drivers/isdn/i4l/isdn_net.c
index 94affa5e6f28..546b7e81161d 100644
--- a/drivers/isdn/i4l/isdn_net.c
+++ b/drivers/isdn/i4l/isdn_net.c
@@ -1951,38 +1951,6 @@ static int isdn_net_header(struct sk_buff *skb, struct net_device *dev,
1951 return len; 1951 return len;
1952} 1952}
1953 1953
1954/* We don't need to send arp, because we have point-to-point connections. */
1955static int
1956isdn_net_rebuild_header(struct sk_buff *skb)
1957{
1958 struct net_device *dev = skb->dev;
1959 isdn_net_local *lp = netdev_priv(dev);
1960 int ret = 0;
1961
1962 if (lp->p_encap == ISDN_NET_ENCAP_ETHER) {
1963 struct ethhdr *eth = (struct ethhdr *) skb->data;
1964
1965 /*
1966 * Only ARP/IP is currently supported
1967 */
1968
1969 if (eth->h_proto != htons(ETH_P_IP)) {
1970 printk(KERN_WARNING
1971 "isdn_net: %s don't know how to resolve type %d addresses?\n",
1972 dev->name, (int) eth->h_proto);
1973 memcpy(eth->h_source, dev->dev_addr, dev->addr_len);
1974 return 0;
1975 }
1976 /*
1977 * Try to get ARP to resolve the header.
1978 */
1979#ifdef CONFIG_INET
1980 ret = arp_find(eth->h_dest, skb);
1981#endif
1982 }
1983 return ret;
1984}
1985
1986static int isdn_header_cache(const struct neighbour *neigh, struct hh_cache *hh, 1954static int isdn_header_cache(const struct neighbour *neigh, struct hh_cache *hh,
1987 __be16 type) 1955 __be16 type)
1988{ 1956{
@@ -2005,7 +1973,6 @@ static void isdn_header_cache_update(struct hh_cache *hh,
2005 1973
2006static const struct header_ops isdn_header_ops = { 1974static const struct header_ops isdn_header_ops = {
2007 .create = isdn_net_header, 1975 .create = isdn_net_header,
2008 .rebuild = isdn_net_rebuild_header,
2009 .cache = isdn_header_cache, 1976 .cache = isdn_header_cache,
2010 .cache_update = isdn_header_cache_update, 1977 .cache_update = isdn_header_cache_update,
2011}; 1978};
diff --git a/drivers/isdn/mISDN/socket.c b/drivers/isdn/mISDN/socket.c
index 84b35925ee4d..8dc7290089bb 100644
--- a/drivers/isdn/mISDN/socket.c
+++ b/drivers/isdn/mISDN/socket.c
@@ -112,8 +112,8 @@ mISDN_sock_cmsg(struct sock *sk, struct msghdr *msg, struct sk_buff *skb)
112} 112}
113 113
114static int 114static int
115mISDN_sock_recvmsg(struct kiocb *iocb, struct socket *sock, 115mISDN_sock_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
116 struct msghdr *msg, size_t len, int flags) 116 int flags)
117{ 117{
118 struct sk_buff *skb; 118 struct sk_buff *skb;
119 struct sock *sk = sock->sk; 119 struct sock *sk = sock->sk;
@@ -173,8 +173,7 @@ mISDN_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
173} 173}
174 174
175static int 175static int
176mISDN_sock_sendmsg(struct kiocb *iocb, struct socket *sock, 176mISDN_sock_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
177 struct msghdr *msg, size_t len)
178{ 177{
179 struct sock *sk = sock->sk; 178 struct sock *sk = sock->sk;
180 struct sk_buff *skb; 179 struct sk_buff *skb;