summary refs log tree commit diff
path: root/net
diff options
context:
space:
mode:
authorUrs Thuermann <urs.thuermann@volkswagen.de>2008-02-07 18:04:45 -0800
committerDavid S. Miller <davem@davemloft.net>2008-02-07 18:04:45 -0800
commita2fea5f19f970b45e854c22cab25250a79613643 (patch)
treeed65426674c487102a98d5d28e6a8b5653525a4a /net
parent5423dd67bd0108a180784c6f307646622e804c9b (diff)
downloadlinux-a2fea5f19f970b45e854c22cab25250a79613643.tar.gz
[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')
-rw-r--r--net/can/af_can.c27
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)
 		return -EINVAL;
 	}
 
+	err = proto_register(cp->prot, 0);
+	if (err < 0)
+		return err;
+
 	spin_lock(&proto_tab_lock);
 	if (proto_tab[proto]) {
 		printk(KERN_ERR "can: protocol %d already registered\n",
 		       proto);
 		err = -EBUSY;
-		goto errout;
+	} else {
+		proto_tab[proto] = cp;
+
+		/* use generic ioctl function if not defined by module */
+		if (!cp->ops->ioctl)
+			cp->ops->ioctl = can_ioctl;
 	}
+	spin_unlock(&proto_tab_lock);
 
-	err = proto_register(cp->prot, 0);
 	if (err < 0)
-		goto errout;
-
-	proto_tab[proto] = cp;
-
-	/* use generic ioctl function if the module doesn't bring its own */
-	if (!cp->ops->ioctl)
-		cp->ops->ioctl = can_ioctl;
-
- errout:
-	spin_unlock(&proto_tab_lock);
+		proto_unregister(cp->prot);
 
 	return err;
 }
@@ -694,9 +694,10 @@ void can_proto_unregister(struct can_proto *cp)
 		printk(KERN_ERR "BUG: can: protocol %d is not registered\n",
 		       proto);
 	}
-	proto_unregister(cp->prot);
 	proto_tab[proto] = NULL;
 	spin_unlock(&proto_tab_lock);
+
+	proto_unregister(cp->prot);
 }
 EXPORT_SYMBOL(can_proto_unregister);