diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-18 13:23:37 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-18 13:23:37 -0400 |
commit | 31bdc5dc7666aa2fe04c626cea30fe3c20cf481c (patch) | |
tree | a1a78a39379e081e9982c3273a71b4e93e8c1fd0 /drivers | |
parent | 5cc97bf2d8eaa6cab60727c3eba3e85e29062669 (diff) | |
parent | a5f8967e171a6fa27da8e6d06d3ef85f7fed43c1 (diff) |
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6
* 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6:
[SPARC64]: Set vio->desc_buf to NULL after freeing.
[SPARC]: Mark sparc and sparc64 as not having virt_to_bus
[SPARC64]: Fix reset handling in VNET driver.
[SPARC64]: Handle reset events in vio_link_state_change().
[SPARC64]: Handle LDC resets properly in domain-services driver.
[SPARC64]: Massively simplify VIO device layer and support hot add/remove.
[SPARC64]: Simplify VNET probing.
[SPARC64]: Simplify VDC device probing.
[SPARC64]: Add basic infrastructure for MD add/remove notification.
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/block/sunvdc.c | 97 | ||||
-rw-r--r-- | drivers/net/sunvnet.c | 260 | ||||
-rw-r--r-- | drivers/net/sunvnet.h | 4 |
3 files changed, 142 insertions, 219 deletions
diff --git a/drivers/block/sunvdc.c b/drivers/block/sunvdc.c index 0f5e3caf85d7..2288b55d916f 100644 --- a/drivers/block/sunvdc.c +++ b/drivers/block/sunvdc.c | |||
@@ -45,8 +45,6 @@ struct vdc_req_entry { | |||
45 | struct vdc_port { | 45 | struct vdc_port { |
46 | struct vio_driver_state vio; | 46 | struct vio_driver_state vio; |
47 | 47 | ||
48 | struct vdc *vp; | ||
49 | |||
50 | struct gendisk *disk; | 48 | struct gendisk *disk; |
51 | 49 | ||
52 | struct vdc_completion *cmp; | 50 | struct vdc_completion *cmp; |
@@ -72,8 +70,6 @@ struct vdc_port { | |||
72 | 70 | ||
73 | struct vio_disk_geom geom; | 71 | struct vio_disk_geom geom; |
74 | struct vio_disk_vtoc label; | 72 | struct vio_disk_vtoc label; |
75 | |||
76 | struct list_head list; | ||
77 | }; | 73 | }; |
78 | 74 | ||
79 | static inline struct vdc_port *to_vdc_port(struct vio_driver_state *vio) | 75 | static inline struct vdc_port *to_vdc_port(struct vio_driver_state *vio) |
@@ -81,15 +77,6 @@ static inline struct vdc_port *to_vdc_port(struct vio_driver_state *vio) | |||
81 | return container_of(vio, struct vdc_port, vio); | 77 | return container_of(vio, struct vdc_port, vio); |
82 | } | 78 | } |
83 | 79 | ||
84 | struct vdc { | ||
85 | /* Protects prot_list. */ | ||
86 | spinlock_t lock; | ||
87 | |||
88 | struct vio_dev *dev; | ||
89 | |||
90 | struct list_head port_list; | ||
91 | }; | ||
92 | |||
93 | /* Ordered from largest major to lowest */ | 80 | /* Ordered from largest major to lowest */ |
94 | static struct vio_version vdc_versions[] = { | 81 | static struct vio_version vdc_versions[] = { |
95 | { .major = 1, .minor = 0 }, | 82 | { .major = 1, .minor = 0 }, |
@@ -747,21 +734,23 @@ static struct vio_driver_ops vdc_vio_ops = { | |||
747 | .handshake_complete = vdc_handshake_complete, | 734 | .handshake_complete = vdc_handshake_complete, |
748 | }; | 735 | }; |
749 | 736 | ||
737 | static void print_version(void) | ||
738 | { | ||
739 | static int version_printed; | ||
740 | |||
741 | if (version_printed++ == 0) | ||
742 | printk(KERN_INFO "%s", version); | ||
743 | } | ||
744 | |||
750 | static int __devinit vdc_port_probe(struct vio_dev *vdev, | 745 | static int __devinit vdc_port_probe(struct vio_dev *vdev, |
751 | const struct vio_device_id *id) | 746 | const struct vio_device_id *id) |
752 | { | 747 | { |
753 | struct mdesc_handle *hp; | 748 | struct mdesc_handle *hp; |
754 | struct vdc_port *port; | 749 | struct vdc_port *port; |
755 | unsigned long flags; | ||
756 | struct vdc *vp; | ||
757 | const u64 *port_id; | 750 | const u64 *port_id; |
758 | int err; | 751 | int err; |
759 | 752 | ||
760 | vp = dev_get_drvdata(vdev->dev.parent); | 753 | print_version(); |
761 | if (!vp) { | ||
762 | printk(KERN_ERR PFX "Cannot find port parent vdc.\n"); | ||
763 | return -ENODEV; | ||
764 | } | ||
765 | 754 | ||
766 | hp = mdesc_grab(); | 755 | hp = mdesc_grab(); |
767 | 756 | ||
@@ -783,7 +772,6 @@ static int __devinit vdc_port_probe(struct vio_dev *vdev, | |||
783 | goto err_out_release_mdesc; | 772 | goto err_out_release_mdesc; |
784 | } | 773 | } |
785 | 774 | ||
786 | port->vp = vp; | ||
787 | port->dev_no = *port_id; | 775 | port->dev_no = *port_id; |
788 | 776 | ||
789 | if (port->dev_no >= 26) | 777 | if (port->dev_no >= 26) |
@@ -818,12 +806,6 @@ static int __devinit vdc_port_probe(struct vio_dev *vdev, | |||
818 | if (err) | 806 | if (err) |
819 | goto err_out_free_tx_ring; | 807 | goto err_out_free_tx_ring; |
820 | 808 | ||
821 | INIT_LIST_HEAD(&port->list); | ||
822 | |||
823 | spin_lock_irqsave(&vp->lock, flags); | ||
824 | list_add(&port->list, &vp->port_list); | ||
825 | spin_unlock_irqrestore(&vp->lock, flags); | ||
826 | |||
827 | dev_set_drvdata(&vdev->dev, port); | 809 | dev_set_drvdata(&vdev->dev, port); |
828 | 810 | ||
829 | mdesc_release(hp); | 811 | mdesc_release(hp); |
@@ -879,58 +861,6 @@ static struct vio_driver vdc_port_driver = { | |||
879 | } | 861 | } |
880 | }; | 862 | }; |
881 | 863 | ||
882 | static int __devinit vdc_probe(struct vio_dev *vdev, | ||
883 | const struct vio_device_id *id) | ||
884 | { | ||
885 | static int vdc_version_printed; | ||
886 | struct vdc *vp; | ||
887 | |||
888 | if (vdc_version_printed++ == 0) | ||
889 | printk(KERN_INFO "%s", version); | ||
890 | |||
891 | vp = kzalloc(sizeof(struct vdc), GFP_KERNEL); | ||
892 | if (!vp) | ||
893 | return -ENOMEM; | ||
894 | |||
895 | spin_lock_init(&vp->lock); | ||
896 | vp->dev = vdev; | ||
897 | INIT_LIST_HEAD(&vp->port_list); | ||
898 | |||
899 | dev_set_drvdata(&vdev->dev, vp); | ||
900 | |||
901 | return 0; | ||
902 | } | ||
903 | |||
904 | static int vdc_remove(struct vio_dev *vdev) | ||
905 | { | ||
906 | |||
907 | struct vdc *vp = dev_get_drvdata(&vdev->dev); | ||
908 | |||
909 | if (vp) { | ||
910 | kfree(vp); | ||
911 | dev_set_drvdata(&vdev->dev, NULL); | ||
912 | } | ||
913 | return 0; | ||
914 | } | ||
915 | |||
916 | static struct vio_device_id vdc_match[] = { | ||
917 | { | ||
918 | .type = "block", | ||
919 | }, | ||
920 | {}, | ||
921 | }; | ||
922 | MODULE_DEVICE_TABLE(vio, vdc_match); | ||
923 | |||
924 | static struct vio_driver vdc_driver = { | ||
925 | .id_table = vdc_match, | ||
926 | .probe = vdc_probe, | ||
927 | .remove = vdc_remove, | ||
928 | .driver = { | ||
929 | .name = "vdc", | ||
930 | .owner = THIS_MODULE, | ||
931 | } | ||
932 | }; | ||
933 | |||
934 | static int __init vdc_init(void) | 864 | static int __init vdc_init(void) |
935 | { | 865 | { |
936 | int err; | 866 | int err; |
@@ -940,19 +870,13 @@ static int __init vdc_init(void) | |||
940 | goto out_err; | 870 | goto out_err; |
941 | 871 | ||
942 | vdc_major = err; | 872 | vdc_major = err; |
943 | err = vio_register_driver(&vdc_driver); | ||
944 | if (err) | ||
945 | goto out_unregister_blkdev; | ||
946 | 873 | ||
947 | err = vio_register_driver(&vdc_port_driver); | 874 | err = vio_register_driver(&vdc_port_driver); |
948 | if (err) | 875 | if (err) |
949 | goto out_unregister_vdc; | 876 | goto out_unregister_blkdev; |
950 | 877 | ||
951 | return 0; | 878 | return 0; |
952 | 879 | ||
953 | out_unregister_vdc: | ||
954 | vio_unregister_driver(&vdc_driver); | ||
955 | |||
956 | out_unregister_blkdev: | 880 | out_unregister_blkdev: |
957 | unregister_blkdev(vdc_major, VDCBLK_NAME); | 881 | unregister_blkdev(vdc_major, VDCBLK_NAME); |
958 | vdc_major = 0; | 882 | vdc_major = 0; |
@@ -964,7 +888,6 @@ out_err: | |||
964 | static void __exit vdc_exit(void) | 888 | static void __exit vdc_exit(void) |
965 | { | 889 | { |
966 | vio_unregister_driver(&vdc_port_driver); | 890 | vio_unregister_driver(&vdc_port_driver); |
967 | vio_unregister_driver(&vdc_driver); | ||
968 | unregister_blkdev(vdc_major, VDCBLK_NAME); | 891 | unregister_blkdev(vdc_major, VDCBLK_NAME); |
969 | } | 892 | } |
970 | 893 | ||
diff --git a/drivers/net/sunvnet.c b/drivers/net/sunvnet.c index 8a667c13faef..b801e3b3a11a 100644 --- a/drivers/net/sunvnet.c +++ b/drivers/net/sunvnet.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/netdevice.h> | 12 | #include <linux/netdevice.h> |
13 | #include <linux/ethtool.h> | 13 | #include <linux/ethtool.h> |
14 | #include <linux/etherdevice.h> | 14 | #include <linux/etherdevice.h> |
15 | #include <linux/mutex.h> | ||
15 | 16 | ||
16 | #include <asm/vio.h> | 17 | #include <asm/vio.h> |
17 | #include <asm/ldc.h> | 18 | #include <asm/ldc.h> |
@@ -497,6 +498,8 @@ static void vnet_event(void *arg, int event) | |||
497 | vio_link_state_change(vio, event); | 498 | vio_link_state_change(vio, event); |
498 | spin_unlock_irqrestore(&vio->lock, flags); | 499 | spin_unlock_irqrestore(&vio->lock, flags); |
499 | 500 | ||
501 | if (event == LDC_EVENT_RESET) | ||
502 | vio_port_up(vio); | ||
500 | return; | 503 | return; |
501 | } | 504 | } |
502 | 505 | ||
@@ -875,6 +878,115 @@ err_out: | |||
875 | return err; | 878 | return err; |
876 | } | 879 | } |
877 | 880 | ||
881 | static LIST_HEAD(vnet_list); | ||
882 | static DEFINE_MUTEX(vnet_list_mutex); | ||
883 | |||
884 | static struct vnet * __devinit vnet_new(const u64 *local_mac) | ||
885 | { | ||
886 | struct net_device *dev; | ||
887 | struct vnet *vp; | ||
888 | int err, i; | ||
889 | |||
890 | dev = alloc_etherdev(sizeof(*vp)); | ||
891 | if (!dev) { | ||
892 | printk(KERN_ERR PFX "Etherdev alloc failed, aborting.\n"); | ||
893 | return ERR_PTR(-ENOMEM); | ||
894 | } | ||
895 | |||
896 | for (i = 0; i < ETH_ALEN; i++) | ||
897 | dev->dev_addr[i] = (*local_mac >> (5 - i) * 8) & 0xff; | ||
898 | |||
899 | memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len); | ||
900 | |||
901 | vp = netdev_priv(dev); | ||
902 | |||
903 | spin_lock_init(&vp->lock); | ||
904 | vp->dev = dev; | ||
905 | |||
906 | INIT_LIST_HEAD(&vp->port_list); | ||
907 | for (i = 0; i < VNET_PORT_HASH_SIZE; i++) | ||
908 | INIT_HLIST_HEAD(&vp->port_hash[i]); | ||
909 | INIT_LIST_HEAD(&vp->list); | ||
910 | vp->local_mac = *local_mac; | ||
911 | |||
912 | dev->open = vnet_open; | ||
913 | dev->stop = vnet_close; | ||
914 | dev->set_multicast_list = vnet_set_rx_mode; | ||
915 | dev->set_mac_address = vnet_set_mac_addr; | ||
916 | dev->tx_timeout = vnet_tx_timeout; | ||
917 | dev->ethtool_ops = &vnet_ethtool_ops; | ||
918 | dev->watchdog_timeo = VNET_TX_TIMEOUT; | ||
919 | dev->change_mtu = vnet_change_mtu; | ||
920 | dev->hard_start_xmit = vnet_start_xmit; | ||
921 | |||
922 | err = register_netdev(dev); | ||
923 | if (err) { | ||
924 | printk(KERN_ERR PFX "Cannot register net device, " | ||
925 | "aborting.\n"); | ||
926 | goto err_out_free_dev; | ||
927 | } | ||
928 | |||
929 | printk(KERN_INFO "%s: Sun LDOM vnet ", dev->name); | ||
930 | |||
931 | for (i = 0; i < 6; i++) | ||
932 | printk("%2.2x%c", dev->dev_addr[i], i == 5 ? '\n' : ':'); | ||
933 | |||
934 | list_add(&vp->list, &vnet_list); | ||
935 | |||
936 | return vp; | ||
937 | |||
938 | err_out_free_dev: | ||
939 | free_netdev(dev); | ||
940 | |||
941 | return ERR_PTR(err); | ||
942 | } | ||
943 | |||
944 | static struct vnet * __devinit vnet_find_or_create(const u64 *local_mac) | ||
945 | { | ||
946 | struct vnet *iter, *vp; | ||
947 | |||
948 | mutex_lock(&vnet_list_mutex); | ||
949 | vp = NULL; | ||
950 | list_for_each_entry(iter, &vnet_list, list) { | ||
951 | if (iter->local_mac == *local_mac) { | ||
952 | vp = iter; | ||
953 | break; | ||
954 | } | ||
955 | } | ||
956 | if (!vp) | ||
957 | vp = vnet_new(local_mac); | ||
958 | mutex_unlock(&vnet_list_mutex); | ||
959 | |||
960 | return vp; | ||
961 | } | ||
962 | |||
963 | static const char *local_mac_prop = "local-mac-address"; | ||
964 | |||
965 | static struct vnet * __devinit vnet_find_parent(struct mdesc_handle *hp, | ||
966 | u64 port_node) | ||
967 | { | ||
968 | const u64 *local_mac = NULL; | ||
969 | u64 a; | ||
970 | |||
971 | mdesc_for_each_arc(a, hp, port_node, MDESC_ARC_TYPE_BACK) { | ||
972 | u64 target = mdesc_arc_target(hp, a); | ||
973 | const char *name; | ||
974 | |||
975 | name = mdesc_get_property(hp, target, "name", NULL); | ||
976 | if (!name || strcmp(name, "network")) | ||
977 | continue; | ||
978 | |||
979 | local_mac = mdesc_get_property(hp, target, | ||
980 | local_mac_prop, NULL); | ||
981 | if (local_mac) | ||
982 | break; | ||
983 | } | ||
984 | if (!local_mac) | ||
985 | return ERR_PTR(-ENODEV); | ||
986 | |||
987 | return vnet_find_or_create(local_mac); | ||
988 | } | ||
989 | |||
878 | static struct ldc_channel_config vnet_ldc_cfg = { | 990 | static struct ldc_channel_config vnet_ldc_cfg = { |
879 | .event = vnet_event, | 991 | .event = vnet_event, |
880 | .mtu = 64, | 992 | .mtu = 64, |
@@ -887,6 +999,14 @@ static struct vio_driver_ops vnet_vio_ops = { | |||
887 | .handshake_complete = vnet_handshake_complete, | 999 | .handshake_complete = vnet_handshake_complete, |
888 | }; | 1000 | }; |
889 | 1001 | ||
1002 | static void print_version(void) | ||
1003 | { | ||
1004 | static int version_printed; | ||
1005 | |||
1006 | if (version_printed++ == 0) | ||
1007 | printk(KERN_INFO "%s", version); | ||
1008 | } | ||
1009 | |||
890 | const char *remote_macaddr_prop = "remote-mac-address"; | 1010 | const char *remote_macaddr_prop = "remote-mac-address"; |
891 | 1011 | ||
892 | static int __devinit vnet_port_probe(struct vio_dev *vdev, | 1012 | static int __devinit vnet_port_probe(struct vio_dev *vdev, |
@@ -899,14 +1019,17 @@ static int __devinit vnet_port_probe(struct vio_dev *vdev, | |||
899 | const u64 *rmac; | 1019 | const u64 *rmac; |
900 | int len, i, err, switch_port; | 1020 | int len, i, err, switch_port; |
901 | 1021 | ||
902 | vp = dev_get_drvdata(vdev->dev.parent); | 1022 | print_version(); |
903 | if (!vp) { | ||
904 | printk(KERN_ERR PFX "Cannot find port parent vnet.\n"); | ||
905 | return -ENODEV; | ||
906 | } | ||
907 | 1023 | ||
908 | hp = mdesc_grab(); | 1024 | hp = mdesc_grab(); |
909 | 1025 | ||
1026 | vp = vnet_find_parent(hp, vdev->mp); | ||
1027 | if (IS_ERR(vp)) { | ||
1028 | printk(KERN_ERR PFX "Cannot find port parent vnet.\n"); | ||
1029 | err = PTR_ERR(vp); | ||
1030 | goto err_out_put_mdesc; | ||
1031 | } | ||
1032 | |||
910 | rmac = mdesc_get_property(hp, vdev->mp, remote_macaddr_prop, &len); | 1033 | rmac = mdesc_get_property(hp, vdev->mp, remote_macaddr_prop, &len); |
911 | err = -ENODEV; | 1034 | err = -ENODEV; |
912 | if (!rmac) { | 1035 | if (!rmac) { |
@@ -1025,139 +1148,14 @@ static struct vio_driver vnet_port_driver = { | |||
1025 | } | 1148 | } |
1026 | }; | 1149 | }; |
1027 | 1150 | ||
1028 | const char *local_mac_prop = "local-mac-address"; | ||
1029 | |||
1030 | static int __devinit vnet_probe(struct vio_dev *vdev, | ||
1031 | const struct vio_device_id *id) | ||
1032 | { | ||
1033 | static int vnet_version_printed; | ||
1034 | struct mdesc_handle *hp; | ||
1035 | struct net_device *dev; | ||
1036 | struct vnet *vp; | ||
1037 | const u64 *mac; | ||
1038 | int err, i, len; | ||
1039 | |||
1040 | if (vnet_version_printed++ == 0) | ||
1041 | printk(KERN_INFO "%s", version); | ||
1042 | |||
1043 | hp = mdesc_grab(); | ||
1044 | |||
1045 | mac = mdesc_get_property(hp, vdev->mp, local_mac_prop, &len); | ||
1046 | if (!mac) { | ||
1047 | printk(KERN_ERR PFX "vnet lacks %s property.\n", | ||
1048 | local_mac_prop); | ||
1049 | err = -ENODEV; | ||
1050 | goto err_out; | ||
1051 | } | ||
1052 | |||
1053 | dev = alloc_etherdev(sizeof(*vp)); | ||
1054 | if (!dev) { | ||
1055 | printk(KERN_ERR PFX "Etherdev alloc failed, aborting.\n"); | ||
1056 | err = -ENOMEM; | ||
1057 | goto err_out; | ||
1058 | } | ||
1059 | |||
1060 | for (i = 0; i < ETH_ALEN; i++) | ||
1061 | dev->dev_addr[i] = (*mac >> (5 - i) * 8) & 0xff; | ||
1062 | |||
1063 | memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len); | ||
1064 | |||
1065 | SET_NETDEV_DEV(dev, &vdev->dev); | ||
1066 | |||
1067 | vp = netdev_priv(dev); | ||
1068 | |||
1069 | spin_lock_init(&vp->lock); | ||
1070 | vp->dev = dev; | ||
1071 | vp->vdev = vdev; | ||
1072 | |||
1073 | INIT_LIST_HEAD(&vp->port_list); | ||
1074 | for (i = 0; i < VNET_PORT_HASH_SIZE; i++) | ||
1075 | INIT_HLIST_HEAD(&vp->port_hash[i]); | ||
1076 | |||
1077 | dev->open = vnet_open; | ||
1078 | dev->stop = vnet_close; | ||
1079 | dev->set_multicast_list = vnet_set_rx_mode; | ||
1080 | dev->set_mac_address = vnet_set_mac_addr; | ||
1081 | dev->tx_timeout = vnet_tx_timeout; | ||
1082 | dev->ethtool_ops = &vnet_ethtool_ops; | ||
1083 | dev->watchdog_timeo = VNET_TX_TIMEOUT; | ||
1084 | dev->change_mtu = vnet_change_mtu; | ||
1085 | dev->hard_start_xmit = vnet_start_xmit; | ||
1086 | |||
1087 | err = register_netdev(dev); | ||
1088 | if (err) { | ||
1089 | printk(KERN_ERR PFX "Cannot register net device, " | ||
1090 | "aborting.\n"); | ||
1091 | goto err_out_free_dev; | ||
1092 | } | ||
1093 | |||
1094 | printk(KERN_INFO "%s: Sun LDOM vnet ", dev->name); | ||
1095 | |||
1096 | for (i = 0; i < 6; i++) | ||
1097 | printk("%2.2x%c", dev->dev_addr[i], i == 5 ? '\n' : ':'); | ||
1098 | |||
1099 | dev_set_drvdata(&vdev->dev, vp); | ||
1100 | |||
1101 | mdesc_release(hp); | ||
1102 | |||
1103 | return 0; | ||
1104 | |||
1105 | err_out_free_dev: | ||
1106 | free_netdev(dev); | ||
1107 | |||
1108 | err_out: | ||
1109 | mdesc_release(hp); | ||
1110 | return err; | ||
1111 | } | ||
1112 | |||
1113 | static int vnet_remove(struct vio_dev *vdev) | ||
1114 | { | ||
1115 | |||
1116 | struct vnet *vp = dev_get_drvdata(&vdev->dev); | ||
1117 | |||
1118 | if (vp) { | ||
1119 | /* XXX unregister port, or at least check XXX */ | ||
1120 | unregister_netdevice(vp->dev); | ||
1121 | dev_set_drvdata(&vdev->dev, NULL); | ||
1122 | } | ||
1123 | return 0; | ||
1124 | } | ||
1125 | |||
1126 | static struct vio_device_id vnet_match[] = { | ||
1127 | { | ||
1128 | .type = "network", | ||
1129 | }, | ||
1130 | {}, | ||
1131 | }; | ||
1132 | MODULE_DEVICE_TABLE(vio, vnet_match); | ||
1133 | |||
1134 | static struct vio_driver vnet_driver = { | ||
1135 | .id_table = vnet_match, | ||
1136 | .probe = vnet_probe, | ||
1137 | .remove = vnet_remove, | ||
1138 | .driver = { | ||
1139 | .name = "vnet", | ||
1140 | .owner = THIS_MODULE, | ||
1141 | } | ||
1142 | }; | ||
1143 | |||
1144 | static int __init vnet_init(void) | 1151 | static int __init vnet_init(void) |
1145 | { | 1152 | { |
1146 | int err = vio_register_driver(&vnet_driver); | 1153 | return vio_register_driver(&vnet_port_driver); |
1147 | |||
1148 | if (!err) { | ||
1149 | err = vio_register_driver(&vnet_port_driver); | ||
1150 | if (err) | ||
1151 | vio_unregister_driver(&vnet_driver); | ||
1152 | } | ||
1153 | |||
1154 | return err; | ||
1155 | } | 1154 | } |
1156 | 1155 | ||
1157 | static void __exit vnet_exit(void) | 1156 | static void __exit vnet_exit(void) |
1158 | { | 1157 | { |
1159 | vio_unregister_driver(&vnet_port_driver); | 1158 | vio_unregister_driver(&vnet_port_driver); |
1160 | vio_unregister_driver(&vnet_driver); | ||
1161 | } | 1159 | } |
1162 | 1160 | ||
1163 | module_init(vnet_init); | 1161 | module_init(vnet_init); |
diff --git a/drivers/net/sunvnet.h b/drivers/net/sunvnet.h index 1c887302d46d..7d3a0cac727b 100644 --- a/drivers/net/sunvnet.h +++ b/drivers/net/sunvnet.h | |||
@@ -60,11 +60,13 @@ struct vnet { | |||
60 | struct net_device *dev; | 60 | struct net_device *dev; |
61 | 61 | ||
62 | u32 msg_enable; | 62 | u32 msg_enable; |
63 | struct vio_dev *vdev; | ||
64 | 63 | ||
65 | struct list_head port_list; | 64 | struct list_head port_list; |
66 | 65 | ||
67 | struct hlist_head port_hash[VNET_PORT_HASH_SIZE]; | 66 | struct hlist_head port_hash[VNET_PORT_HASH_SIZE]; |
67 | |||
68 | struct list_head list; | ||
69 | u64 local_mac; | ||
68 | }; | 70 | }; |
69 | 71 | ||
70 | #endif /* _SUNVNET_H */ | 72 | #endif /* _SUNVNET_H */ |