diff options
author | Urs Thuermann <urs.thuermann@volkswagen.de> | 2008-02-07 21:04:45 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-02-07 21:04:45 -0500 |
commit | a2fea5f19f970b45e854c22cab25250a79613643 (patch) | |
tree | ed65426674c487102a98d5d28e6a8b5653525a4a /net/can/af_can.c | |
parent | 5423dd67bd0108a180784c6f307646622e804c9b (diff) |
[CAN]: Move proto_{,un}register() out of spin-locked region
The implementation of proto_register() has changed so that it can now
sleep. The call to proto_register() must be moved out of the
spin-locked region.
Signed-off-by: Urs Thuermann <urs.thuermann@volkswagen.de>
Signed-off-by: Oliver Hartkopp <oliver.hartkopp@volkswagen.de>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/can/af_can.c')
-rw-r--r-- | net/can/af_can.c | 27 |
1 files changed, 14 insertions, 13 deletions
diff --git a/net/can/af_can.c b/net/can/af_can.c index 1f51b8a18242..36b9f22ed83a 100644 --- a/net/can/af_can.c +++ b/net/can/af_can.c | |||
@@ -656,26 +656,26 @@ int can_proto_register(struct can_proto *cp) | |||
656 | return -EINVAL; | 656 | return -EINVAL; |
657 | } | 657 | } |
658 | 658 | ||
659 | err = proto_register(cp->prot, 0); | ||
660 | if (err < 0) | ||
661 | return err; | ||
662 | |||
659 | spin_lock(&proto_tab_lock); | 663 | spin_lock(&proto_tab_lock); |
660 | if (proto_tab[proto]) { | 664 | if (proto_tab[proto]) { |
661 | printk(KERN_ERR "can: protocol %d already registered\n", | 665 | printk(KERN_ERR "can: protocol %d already registered\n", |
662 | proto); | 666 | proto); |
663 | err = -EBUSY; | 667 | err = -EBUSY; |
664 | goto errout; | 668 | } else { |
669 | proto_tab[proto] = cp; | ||
670 | |||
671 | /* use generic ioctl function if not defined by module */ | ||
672 | if (!cp->ops->ioctl) | ||
673 | cp->ops->ioctl = can_ioctl; | ||
665 | } | 674 | } |
675 | spin_unlock(&proto_tab_lock); | ||
666 | 676 | ||
667 | err = proto_register(cp->prot, 0); | ||
668 | if (err < 0) | 677 | if (err < 0) |
669 | goto errout; | 678 | proto_unregister(cp->prot); |
670 | |||
671 | proto_tab[proto] = cp; | ||
672 | |||
673 | /* use generic ioctl function if the module doesn't bring its own */ | ||
674 | if (!cp->ops->ioctl) | ||
675 | cp->ops->ioctl = can_ioctl; | ||
676 | |||
677 | errout: | ||
678 | spin_unlock(&proto_tab_lock); | ||
679 | 679 | ||
680 | return err; | 680 | return err; |
681 | } | 681 | } |
@@ -694,9 +694,10 @@ void can_proto_unregister(struct can_proto *cp) | |||
694 | printk(KERN_ERR "BUG: can: protocol %d is not registered\n", | 694 | printk(KERN_ERR "BUG: can: protocol %d is not registered\n", |
695 | proto); | 695 | proto); |
696 | } | 696 | } |
697 | proto_unregister(cp->prot); | ||
698 | proto_tab[proto] = NULL; | 697 | proto_tab[proto] = NULL; |
699 | spin_unlock(&proto_tab_lock); | 698 | spin_unlock(&proto_tab_lock); |
699 | |||
700 | proto_unregister(cp->prot); | ||
700 | } | 701 | } |
701 | EXPORT_SYMBOL(can_proto_unregister); | 702 | EXPORT_SYMBOL(can_proto_unregister); |
702 | 703 | ||