diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/um/drivers/net_kern.c | 42 |
1 files changed, 18 insertions, 24 deletions
diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c index c1838645ae28..04e31f86c10a 100644 --- a/arch/um/drivers/net_kern.c +++ b/arch/um/drivers/net_kern.c | |||
@@ -502,7 +502,7 @@ static DEFINE_SPINLOCK(transports_lock); | |||
502 | static LIST_HEAD(transports); | 502 | static LIST_HEAD(transports); |
503 | 503 | ||
504 | /* Filled in during early boot */ | 504 | /* Filled in during early boot */ |
505 | struct list_head eth_cmd_line = LIST_HEAD_INIT(eth_cmd_line); | 505 | static LIST_HEAD(eth_cmd_line); |
506 | 506 | ||
507 | static int check_transport(struct transport *transport, char *eth, int n, | 507 | static int check_transport(struct transport *transport, char *eth, int n, |
508 | void **init_out, char **mac_out) | 508 | void **init_out, char **mac_out) |
@@ -563,7 +563,9 @@ static int eth_setup_common(char *str, int index) | |||
563 | struct transport *transport; | 563 | struct transport *transport; |
564 | void *init; | 564 | void *init; |
565 | char *mac = NULL; | 565 | char *mac = NULL; |
566 | int found = 0; | ||
566 | 567 | ||
568 | spin_lock(&transports_lock); | ||
567 | list_for_each(ele, &transports){ | 569 | list_for_each(ele, &transports){ |
568 | transport = list_entry(ele, struct transport, list); | 570 | transport = list_entry(ele, struct transport, list); |
569 | if(!check_transport(transport, str, index, &init, &mac)) | 571 | if(!check_transport(transport, str, index, &init, &mac)) |
@@ -572,9 +574,12 @@ static int eth_setup_common(char *str, int index) | |||
572 | eth_configure(index, init, mac, transport); | 574 | eth_configure(index, init, mac, transport); |
573 | kfree(init); | 575 | kfree(init); |
574 | } | 576 | } |
575 | return 1; | 577 | found = 1; |
578 | break; | ||
576 | } | 579 | } |
577 | return 0; | 580 | |
581 | spin_unlock(&transports_lock); | ||
582 | return found; | ||
578 | } | 583 | } |
579 | 584 | ||
580 | static int eth_setup(char *str) | 585 | static int eth_setup(char *str) |
@@ -610,24 +615,6 @@ __uml_help(eth_setup, | |||
610 | " Configure a network device.\n\n" | 615 | " Configure a network device.\n\n" |
611 | ); | 616 | ); |
612 | 617 | ||
613 | #if 0 | ||
614 | static int eth_init(void) | ||
615 | { | ||
616 | struct list_head *ele, *next; | ||
617 | struct eth_init *eth; | ||
618 | |||
619 | list_for_each_safe(ele, next, ð_cmd_line){ | ||
620 | eth = list_entry(ele, struct eth_init, list); | ||
621 | |||
622 | if(eth_setup_common(eth->init, eth->index)) | ||
623 | list_del(ð->list); | ||
624 | } | ||
625 | |||
626 | return(1); | ||
627 | } | ||
628 | __initcall(eth_init); | ||
629 | #endif | ||
630 | |||
631 | static int net_config(char *str, char **error_out) | 618 | static int net_config(char *str, char **error_out) |
632 | { | 619 | { |
633 | int n, err; | 620 | int n, err; |
@@ -729,6 +716,7 @@ static int uml_inetaddr_event(struct notifier_block *this, unsigned long event, | |||
729 | return NOTIFY_DONE; | 716 | return NOTIFY_DONE; |
730 | } | 717 | } |
731 | 718 | ||
719 | /* uml_net_init shouldn't be called twice on two CPUs at the same time */ | ||
732 | struct notifier_block uml_inetaddr_notifier = { | 720 | struct notifier_block uml_inetaddr_notifier = { |
733 | .notifier_call = uml_inetaddr_event, | 721 | .notifier_call = uml_inetaddr_event, |
734 | }; | 722 | }; |
@@ -747,18 +735,21 @@ static int uml_net_init(void) | |||
747 | * didn't get a chance to run for them. This fakes it so that | 735 | * didn't get a chance to run for them. This fakes it so that |
748 | * addresses which have already been set up get handled properly. | 736 | * addresses which have already been set up get handled properly. |
749 | */ | 737 | */ |
738 | spin_lock(&opened_lock); | ||
750 | list_for_each(ele, &opened){ | 739 | list_for_each(ele, &opened){ |
751 | lp = list_entry(ele, struct uml_net_private, list); | 740 | lp = list_entry(ele, struct uml_net_private, list); |
752 | ip = lp->dev->ip_ptr; | 741 | ip = lp->dev->ip_ptr; |
753 | if(ip == NULL) continue; | 742 | if(ip == NULL) |
743 | continue; | ||
754 | in = ip->ifa_list; | 744 | in = ip->ifa_list; |
755 | while(in != NULL){ | 745 | while(in != NULL){ |
756 | uml_inetaddr_event(NULL, NETDEV_UP, in); | 746 | uml_inetaddr_event(NULL, NETDEV_UP, in); |
757 | in = in->ifa_next; | 747 | in = in->ifa_next; |
758 | } | 748 | } |
759 | } | 749 | } |
750 | spin_unlock(&opened_lock); | ||
760 | 751 | ||
761 | return(0); | 752 | return 0; |
762 | } | 753 | } |
763 | 754 | ||
764 | __initcall(uml_net_init); | 755 | __initcall(uml_net_init); |
@@ -768,13 +759,16 @@ static void close_devices(void) | |||
768 | struct list_head *ele; | 759 | struct list_head *ele; |
769 | struct uml_net_private *lp; | 760 | struct uml_net_private *lp; |
770 | 761 | ||
762 | spin_lock(&opened_lock); | ||
771 | list_for_each(ele, &opened){ | 763 | list_for_each(ele, &opened){ |
772 | lp = list_entry(ele, struct uml_net_private, list); | 764 | lp = list_entry(ele, struct uml_net_private, list); |
773 | free_irq(lp->dev->irq, lp->dev); | 765 | free_irq(lp->dev->irq, lp->dev); |
774 | if((lp->close != NULL) && (lp->fd >= 0)) | 766 | if((lp->close != NULL) && (lp->fd >= 0)) |
775 | (*lp->close)(lp->fd, &lp->user); | 767 | (*lp->close)(lp->fd, &lp->user); |
776 | if(lp->remove != NULL) (*lp->remove)(&lp->user); | 768 | if(lp->remove != NULL) |
769 | (*lp->remove)(&lp->user); | ||
777 | } | 770 | } |
771 | spin_unlock(&opened_lock); | ||
778 | } | 772 | } |
779 | 773 | ||
780 | __uml_exitcall(close_devices); | 774 | __uml_exitcall(close_devices); |