diff options
| -rw-r--r-- | arch/sparc/Kconfig | 3 | ||||
| -rw-r--r-- | arch/sparc64/Kconfig | 3 | ||||
| -rw-r--r-- | arch/sparc64/kernel/ds.c | 19 | ||||
| -rw-r--r-- | arch/sparc64/kernel/mdesc.c | 78 | ||||
| -rw-r--r-- | arch/sparc64/kernel/vio.c | 94 | ||||
| -rw-r--r-- | arch/sparc64/kernel/viohs.c | 30 | ||||
| -rw-r--r-- | drivers/block/sunvdc.c | 97 | ||||
| -rw-r--r-- | drivers/net/sunvnet.c | 260 | ||||
| -rw-r--r-- | drivers/net/sunvnet.h | 4 | ||||
| -rw-r--r-- | include/asm-sparc64/io.h | 5 | ||||
| -rw-r--r-- | include/asm-sparc64/mdesc.h | 10 | ||||
| -rw-r--r-- | include/asm-sparc64/vio.h | 2 |
12 files changed, 344 insertions, 261 deletions
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index 73df7115325b..603d83ad65c8 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig | |||
| @@ -21,6 +21,9 @@ config GENERIC_ISA_DMA | |||
| 21 | bool | 21 | bool |
| 22 | default y | 22 | default y |
| 23 | 23 | ||
| 24 | config ARCH_NO_VIRT_TO_BUS | ||
| 25 | def_bool y | ||
| 26 | |||
| 24 | source "init/Kconfig" | 27 | source "init/Kconfig" |
| 25 | 28 | ||
| 26 | menu "General machine setup" | 29 | menu "General machine setup" |
diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig index b84b6af1241e..df6ee71894d1 100644 --- a/arch/sparc64/Kconfig +++ b/arch/sparc64/Kconfig | |||
| @@ -62,6 +62,9 @@ config AUDIT_ARCH | |||
| 62 | bool | 62 | bool |
| 63 | default y | 63 | default y |
| 64 | 64 | ||
| 65 | config ARCH_NO_VIRT_TO_BUS | ||
| 66 | def_bool y | ||
| 67 | |||
| 65 | choice | 68 | choice |
| 66 | prompt "Kernel page size" | 69 | prompt "Kernel page size" |
| 67 | default SPARC64_PAGE_SIZE_8KB | 70 | default SPARC64_PAGE_SIZE_8KB |
diff --git a/arch/sparc64/kernel/ds.c b/arch/sparc64/kernel/ds.c index ba01533f4e03..fa1f04d756a2 100644 --- a/arch/sparc64/kernel/ds.c +++ b/arch/sparc64/kernel/ds.c | |||
| @@ -1013,6 +1013,19 @@ static void ds_up(struct ds_info *dp) | |||
| 1013 | dp->hs_state = DS_HS_START; | 1013 | dp->hs_state = DS_HS_START; |
| 1014 | } | 1014 | } |
| 1015 | 1015 | ||
| 1016 | static void ds_reset(struct ds_info *dp) | ||
| 1017 | { | ||
| 1018 | int i; | ||
| 1019 | |||
| 1020 | dp->hs_state = 0; | ||
| 1021 | |||
| 1022 | for (i = 0; i < ARRAY_SIZE(ds_states); i++) { | ||
| 1023 | struct ds_cap_state *cp = &ds_states[i]; | ||
| 1024 | |||
| 1025 | cp->state = CAP_STATE_UNKNOWN; | ||
| 1026 | } | ||
| 1027 | } | ||
| 1028 | |||
| 1016 | static void ds_event(void *arg, int event) | 1029 | static void ds_event(void *arg, int event) |
| 1017 | { | 1030 | { |
| 1018 | struct ds_info *dp = arg; | 1031 | struct ds_info *dp = arg; |
| @@ -1028,6 +1041,12 @@ static void ds_event(void *arg, int event) | |||
| 1028 | return; | 1041 | return; |
| 1029 | } | 1042 | } |
| 1030 | 1043 | ||
| 1044 | if (event == LDC_EVENT_RESET) { | ||
| 1045 | ds_reset(dp); | ||
| 1046 | spin_unlock_irqrestore(&ds_lock, flags); | ||
| 1047 | return; | ||
| 1048 | } | ||
| 1049 | |||
| 1031 | if (event != LDC_EVENT_DATA_READY) { | 1050 | if (event != LDC_EVENT_DATA_READY) { |
| 1032 | printk(KERN_WARNING PFX "Unexpected LDC event %d\n", event); | 1051 | printk(KERN_WARNING PFX "Unexpected LDC event %d\n", event); |
| 1033 | spin_unlock_irqrestore(&ds_lock, flags); | 1052 | spin_unlock_irqrestore(&ds_lock, flags); |
diff --git a/arch/sparc64/kernel/mdesc.c b/arch/sparc64/kernel/mdesc.c index de5310ffdb48..302ba5e5a0bb 100644 --- a/arch/sparc64/kernel/mdesc.c +++ b/arch/sparc64/kernel/mdesc.c | |||
| @@ -137,7 +137,7 @@ static struct mdesc_handle *mdesc_kmalloc(unsigned int mdesc_size) | |||
| 137 | sizeof(struct mdesc_hdr) + | 137 | sizeof(struct mdesc_hdr) + |
| 138 | mdesc_size); | 138 | mdesc_size); |
| 139 | 139 | ||
| 140 | base = kmalloc(handle_size + 15, GFP_KERNEL); | 140 | base = kmalloc(handle_size + 15, GFP_KERNEL | __GFP_NOFAIL); |
| 141 | if (base) { | 141 | if (base) { |
| 142 | struct mdesc_handle *hp; | 142 | struct mdesc_handle *hp; |
| 143 | unsigned long addr; | 143 | unsigned long addr; |
| @@ -214,18 +214,83 @@ void mdesc_release(struct mdesc_handle *hp) | |||
| 214 | } | 214 | } |
| 215 | EXPORT_SYMBOL(mdesc_release); | 215 | EXPORT_SYMBOL(mdesc_release); |
| 216 | 216 | ||
| 217 | static DEFINE_MUTEX(mdesc_mutex); | ||
| 218 | static struct mdesc_notifier_client *client_list; | ||
| 219 | |||
| 220 | void mdesc_register_notifier(struct mdesc_notifier_client *client) | ||
| 221 | { | ||
| 222 | u64 node; | ||
| 223 | |||
| 224 | mutex_lock(&mdesc_mutex); | ||
| 225 | client->next = client_list; | ||
| 226 | client_list = client; | ||
| 227 | |||
| 228 | mdesc_for_each_node_by_name(cur_mdesc, node, client->node_name) | ||
| 229 | client->add(cur_mdesc, node); | ||
| 230 | |||
| 231 | mutex_unlock(&mdesc_mutex); | ||
| 232 | } | ||
| 233 | |||
| 234 | /* Run 'func' on nodes which are in A but not in B. */ | ||
| 235 | static void invoke_on_missing(const char *name, | ||
| 236 | struct mdesc_handle *a, | ||
| 237 | struct mdesc_handle *b, | ||
| 238 | void (*func)(struct mdesc_handle *, u64)) | ||
| 239 | { | ||
| 240 | u64 node; | ||
| 241 | |||
| 242 | mdesc_for_each_node_by_name(a, node, name) { | ||
| 243 | const u64 *id = mdesc_get_property(a, node, "id", NULL); | ||
| 244 | int found = 0; | ||
| 245 | u64 fnode; | ||
| 246 | |||
| 247 | mdesc_for_each_node_by_name(b, fnode, name) { | ||
| 248 | const u64 *fid = mdesc_get_property(b, fnode, | ||
| 249 | "id", NULL); | ||
| 250 | |||
| 251 | if (*id == *fid) { | ||
| 252 | found = 1; | ||
| 253 | break; | ||
| 254 | } | ||
| 255 | } | ||
| 256 | if (!found) | ||
| 257 | func(a, node); | ||
| 258 | } | ||
| 259 | } | ||
| 260 | |||
| 261 | static void notify_one(struct mdesc_notifier_client *p, | ||
| 262 | struct mdesc_handle *old_hp, | ||
| 263 | struct mdesc_handle *new_hp) | ||
| 264 | { | ||
| 265 | invoke_on_missing(p->node_name, old_hp, new_hp, p->remove); | ||
| 266 | invoke_on_missing(p->node_name, new_hp, old_hp, p->add); | ||
| 267 | } | ||
| 268 | |||
| 269 | static void mdesc_notify_clients(struct mdesc_handle *old_hp, | ||
| 270 | struct mdesc_handle *new_hp) | ||
| 271 | { | ||
| 272 | struct mdesc_notifier_client *p = client_list; | ||
| 273 | |||
| 274 | while (p) { | ||
| 275 | notify_one(p, old_hp, new_hp); | ||
| 276 | p = p->next; | ||
| 277 | } | ||
| 278 | } | ||
| 279 | |||
| 217 | void mdesc_update(void) | 280 | void mdesc_update(void) |
| 218 | { | 281 | { |
| 219 | unsigned long len, real_len, status; | 282 | unsigned long len, real_len, status; |
| 220 | struct mdesc_handle *hp, *orig_hp; | 283 | struct mdesc_handle *hp, *orig_hp; |
| 221 | unsigned long flags; | 284 | unsigned long flags; |
| 222 | 285 | ||
| 286 | mutex_lock(&mdesc_mutex); | ||
| 287 | |||
| 223 | (void) sun4v_mach_desc(0UL, 0UL, &len); | 288 | (void) sun4v_mach_desc(0UL, 0UL, &len); |
| 224 | 289 | ||
| 225 | hp = mdesc_alloc(len, &kmalloc_mdesc_memops); | 290 | hp = mdesc_alloc(len, &kmalloc_mdesc_memops); |
| 226 | if (!hp) { | 291 | if (!hp) { |
| 227 | printk(KERN_ERR "MD: mdesc alloc fails\n"); | 292 | printk(KERN_ERR "MD: mdesc alloc fails\n"); |
| 228 | return; | 293 | goto out; |
| 229 | } | 294 | } |
| 230 | 295 | ||
| 231 | status = sun4v_mach_desc(__pa(&hp->mdesc), len, &real_len); | 296 | status = sun4v_mach_desc(__pa(&hp->mdesc), len, &real_len); |
| @@ -234,18 +299,25 @@ void mdesc_update(void) | |||
| 234 | status); | 299 | status); |
| 235 | atomic_dec(&hp->refcnt); | 300 | atomic_dec(&hp->refcnt); |
| 236 | mdesc_free(hp); | 301 | mdesc_free(hp); |
| 237 | return; | 302 | goto out; |
| 238 | } | 303 | } |
| 239 | 304 | ||
| 240 | spin_lock_irqsave(&mdesc_lock, flags); | 305 | spin_lock_irqsave(&mdesc_lock, flags); |
| 241 | orig_hp = cur_mdesc; | 306 | orig_hp = cur_mdesc; |
| 242 | cur_mdesc = hp; | 307 | cur_mdesc = hp; |
| 308 | spin_unlock_irqrestore(&mdesc_lock, flags); | ||
| 243 | 309 | ||
| 310 | mdesc_notify_clients(orig_hp, hp); | ||
| 311 | |||
| 312 | spin_lock_irqsave(&mdesc_lock, flags); | ||
| 244 | if (atomic_dec_and_test(&orig_hp->refcnt)) | 313 | if (atomic_dec_and_test(&orig_hp->refcnt)) |
| 245 | mdesc_free(orig_hp); | 314 | mdesc_free(orig_hp); |
| 246 | else | 315 | else |
| 247 | list_add(&orig_hp->list, &mdesc_zombie_list); | 316 | list_add(&orig_hp->list, &mdesc_zombie_list); |
| 248 | spin_unlock_irqrestore(&mdesc_lock, flags); | 317 | spin_unlock_irqrestore(&mdesc_lock, flags); |
| 318 | |||
| 319 | out: | ||
| 320 | mutex_unlock(&mdesc_mutex); | ||
| 249 | } | 321 | } |
| 250 | 322 | ||
| 251 | static struct mdesc_elem *node_block(struct mdesc_hdr *mdesc) | 323 | static struct mdesc_elem *node_block(struct mdesc_hdr *mdesc) |
diff --git a/arch/sparc64/kernel/vio.c b/arch/sparc64/kernel/vio.c index 49569b44ea1f..8d3cc4fdb557 100644 --- a/arch/sparc64/kernel/vio.c +++ b/arch/sparc64/kernel/vio.c | |||
| @@ -201,10 +201,11 @@ static void vio_fill_channel_info(struct mdesc_handle *hp, u64 mp, | |||
| 201 | static struct vio_dev *vio_create_one(struct mdesc_handle *hp, u64 mp, | 201 | static struct vio_dev *vio_create_one(struct mdesc_handle *hp, u64 mp, |
| 202 | struct device *parent) | 202 | struct device *parent) |
| 203 | { | 203 | { |
| 204 | const char *type, *compat; | 204 | const char *type, *compat, *bus_id_name; |
| 205 | struct device_node *dp; | 205 | struct device_node *dp; |
| 206 | struct vio_dev *vdev; | 206 | struct vio_dev *vdev; |
| 207 | int err, tlen, clen; | 207 | int err, tlen, clen; |
| 208 | const u64 *id; | ||
| 208 | 209 | ||
| 209 | type = mdesc_get_property(hp, mp, "device-type", &tlen); | 210 | type = mdesc_get_property(hp, mp, "device-type", &tlen); |
| 210 | if (!type) { | 211 | if (!type) { |
| @@ -220,6 +221,16 @@ static struct vio_dev *vio_create_one(struct mdesc_handle *hp, u64 mp, | |||
| 220 | return NULL; | 221 | return NULL; |
| 221 | } | 222 | } |
| 222 | 223 | ||
| 224 | bus_id_name = type; | ||
| 225 | if (!strcmp(type, "domain-services-port")) | ||
| 226 | bus_id_name = "ds"; | ||
| 227 | |||
| 228 | if (strlen(bus_id_name) >= KOBJ_NAME_LEN - 4) { | ||
| 229 | printk(KERN_ERR "VIO: bus_id_name [%s] is too long.\n", | ||
| 230 | bus_id_name); | ||
| 231 | return NULL; | ||
| 232 | } | ||
| 233 | |||
| 223 | compat = mdesc_get_property(hp, mp, "device-type", &clen); | 234 | compat = mdesc_get_property(hp, mp, "device-type", &clen); |
| 224 | if (!compat) { | 235 | if (!compat) { |
| 225 | clen = 0; | 236 | clen = 0; |
| @@ -249,7 +260,14 @@ static struct vio_dev *vio_create_one(struct mdesc_handle *hp, u64 mp, | |||
| 249 | 260 | ||
| 250 | vio_fill_channel_info(hp, mp, vdev); | 261 | vio_fill_channel_info(hp, mp, vdev); |
| 251 | 262 | ||
| 252 | snprintf(vdev->dev.bus_id, BUS_ID_SIZE, "%lx", mp); | 263 | id = mdesc_get_property(hp, mp, "id", NULL); |
| 264 | if (!id) | ||
| 265 | snprintf(vdev->dev.bus_id, BUS_ID_SIZE, "%s", | ||
| 266 | bus_id_name); | ||
| 267 | else | ||
| 268 | snprintf(vdev->dev.bus_id, BUS_ID_SIZE, "%s-%lu", | ||
| 269 | bus_id_name, *id); | ||
| 270 | |||
| 253 | vdev->dev.parent = parent; | 271 | vdev->dev.parent = parent; |
| 254 | vdev->dev.bus = &vio_bus_type; | 272 | vdev->dev.bus = &vio_bus_type; |
| 255 | vdev->dev.release = vio_dev_release; | 273 | vdev->dev.release = vio_dev_release; |
| @@ -269,6 +287,8 @@ static struct vio_dev *vio_create_one(struct mdesc_handle *hp, u64 mp, | |||
| 269 | } | 287 | } |
| 270 | vdev->dp = dp; | 288 | vdev->dp = dp; |
| 271 | 289 | ||
| 290 | printk(KERN_ERR "VIO: Adding device %s\n", vdev->dev.bus_id); | ||
| 291 | |||
| 272 | err = device_register(&vdev->dev); | 292 | err = device_register(&vdev->dev); |
| 273 | if (err) { | 293 | if (err) { |
| 274 | printk(KERN_ERR "VIO: Could not register device %s, err=%d\n", | 294 | printk(KERN_ERR "VIO: Could not register device %s, err=%d\n", |
| @@ -283,46 +303,46 @@ static struct vio_dev *vio_create_one(struct mdesc_handle *hp, u64 mp, | |||
| 283 | return vdev; | 303 | return vdev; |
| 284 | } | 304 | } |
| 285 | 305 | ||
| 286 | static void walk_tree(struct mdesc_handle *hp, u64 n, struct vio_dev *parent) | 306 | static void vio_add(struct mdesc_handle *hp, u64 node) |
| 287 | { | 307 | { |
| 288 | u64 a; | 308 | (void) vio_create_one(hp, node, &root_vdev->dev); |
| 289 | |||
| 290 | mdesc_for_each_arc(a, hp, n, MDESC_ARC_TYPE_FWD) { | ||
| 291 | struct vio_dev *vdev; | ||
| 292 | u64 target; | ||
| 293 | |||
| 294 | target = mdesc_arc_target(hp, a); | ||
| 295 | vdev = vio_create_one(hp, target, &parent->dev); | ||
| 296 | if (vdev) | ||
| 297 | walk_tree(hp, target, vdev); | ||
| 298 | } | ||
| 299 | } | 309 | } |
| 300 | 310 | ||
| 301 | static void create_devices(struct mdesc_handle *hp, u64 root) | 311 | static int vio_md_node_match(struct device *dev, void *arg) |
| 302 | { | 312 | { |
| 303 | u64 mp; | 313 | struct vio_dev *vdev = to_vio_dev(dev); |
| 304 | 314 | ||
| 305 | root_vdev = vio_create_one(hp, root, NULL); | 315 | if (vdev->mp == (u64) arg) |
| 306 | if (!root_vdev) { | 316 | return 1; |
| 307 | printk(KERN_ERR "VIO: Coult not create root device.\n"); | ||
| 308 | return; | ||
| 309 | } | ||
| 310 | 317 | ||
| 311 | walk_tree(hp, root, root_vdev); | 318 | return 0; |
| 319 | } | ||
| 320 | |||
| 321 | static void vio_remove(struct mdesc_handle *hp, u64 node) | ||
| 322 | { | ||
| 323 | struct device *dev; | ||
| 312 | 324 | ||
| 313 | /* Domain services is odd as it doesn't sit underneath the | 325 | dev = device_find_child(&root_vdev->dev, (void *) node, |
| 314 | * channel-devices node, so we plug it in manually. | 326 | vio_md_node_match); |
| 315 | */ | 327 | if (dev) { |
| 316 | mp = mdesc_node_by_name(hp, MDESC_NODE_NULL, "domain-services"); | 328 | printk(KERN_INFO "VIO: Removing device %s\n", dev->bus_id); |
| 317 | if (mp != MDESC_NODE_NULL) { | ||
| 318 | struct vio_dev *parent = vio_create_one(hp, mp, | ||
| 319 | &root_vdev->dev); | ||
| 320 | 329 | ||
| 321 | if (parent) | 330 | device_unregister(dev); |
| 322 | walk_tree(hp, mp, parent); | ||
| 323 | } | 331 | } |
| 324 | } | 332 | } |
| 325 | 333 | ||
| 334 | static struct mdesc_notifier_client vio_device_notifier = { | ||
| 335 | .add = vio_add, | ||
| 336 | .remove = vio_remove, | ||
| 337 | .node_name = "virtual-device-port", | ||
| 338 | }; | ||
| 339 | |||
| 340 | static struct mdesc_notifier_client vio_ds_notifier = { | ||
| 341 | .add = vio_add, | ||
| 342 | .remove = vio_remove, | ||
| 343 | .node_name = "domain-services-port", | ||
| 344 | }; | ||
| 345 | |||
| 326 | const char *channel_devices_node = "channel-devices"; | 346 | const char *channel_devices_node = "channel-devices"; |
| 327 | const char *channel_devices_compat = "SUNW,sun4v-channel-devices"; | 347 | const char *channel_devices_compat = "SUNW,sun4v-channel-devices"; |
| 328 | const char *cfg_handle_prop = "cfg-handle"; | 348 | const char *cfg_handle_prop = "cfg-handle"; |
| @@ -381,11 +401,19 @@ static int __init vio_init(void) | |||
| 381 | 401 | ||
| 382 | cdev_cfg_handle = *cfg_handle; | 402 | cdev_cfg_handle = *cfg_handle; |
| 383 | 403 | ||
| 384 | create_devices(hp, root); | 404 | root_vdev = vio_create_one(hp, root, NULL); |
| 405 | err = -ENODEV; | ||
| 406 | if (!root_vdev) { | ||
| 407 | printk(KERN_ERR "VIO: Coult not create root device.\n"); | ||
| 408 | goto out_release; | ||
| 409 | } | ||
| 410 | |||
| 411 | mdesc_register_notifier(&vio_device_notifier); | ||
| 412 | mdesc_register_notifier(&vio_ds_notifier); | ||
| 385 | 413 | ||
| 386 | mdesc_release(hp); | 414 | mdesc_release(hp); |
| 387 | 415 | ||
| 388 | return 0; | 416 | return err; |
| 389 | 417 | ||
| 390 | out_release: | 418 | out_release: |
| 391 | mdesc_release(hp); | 419 | mdesc_release(hp); |
diff --git a/arch/sparc64/kernel/viohs.c b/arch/sparc64/kernel/viohs.c index 15613add45d1..09126fc338ba 100644 --- a/arch/sparc64/kernel/viohs.c +++ b/arch/sparc64/kernel/viohs.c | |||
| @@ -78,6 +78,24 @@ static int start_handshake(struct vio_driver_state *vio) | |||
| 78 | return 0; | 78 | return 0; |
| 79 | } | 79 | } |
| 80 | 80 | ||
| 81 | static void flush_rx_dring(struct vio_driver_state *vio) | ||
| 82 | { | ||
| 83 | struct vio_dring_state *dr; | ||
| 84 | u64 ident; | ||
| 85 | |||
| 86 | BUG_ON(!(vio->dr_state & VIO_DR_STATE_RXREG)); | ||
| 87 | |||
| 88 | dr = &vio->drings[VIO_DRIVER_RX_RING]; | ||
| 89 | ident = dr->ident; | ||
| 90 | |||
| 91 | BUG_ON(!vio->desc_buf); | ||
| 92 | kfree(vio->desc_buf); | ||
| 93 | vio->desc_buf = NULL; | ||
| 94 | |||
| 95 | memset(dr, 0, sizeof(*dr)); | ||
| 96 | dr->ident = ident; | ||
| 97 | } | ||
| 98 | |||
| 81 | void vio_link_state_change(struct vio_driver_state *vio, int event) | 99 | void vio_link_state_change(struct vio_driver_state *vio, int event) |
| 82 | { | 100 | { |
| 83 | if (event == LDC_EVENT_UP) { | 101 | if (event == LDC_EVENT_UP) { |
| @@ -98,6 +116,16 @@ void vio_link_state_change(struct vio_driver_state *vio, int event) | |||
| 98 | break; | 116 | break; |
| 99 | } | 117 | } |
| 100 | start_handshake(vio); | 118 | start_handshake(vio); |
| 119 | } else if (event == LDC_EVENT_RESET) { | ||
| 120 | vio->hs_state = VIO_HS_INVALID; | ||
| 121 | |||
| 122 | if (vio->dr_state & VIO_DR_STATE_RXREG) | ||
| 123 | flush_rx_dring(vio); | ||
| 124 | |||
| 125 | vio->dr_state = 0x00; | ||
| 126 | memset(&vio->ver, 0, sizeof(vio->ver)); | ||
| 127 | |||
| 128 | ldc_disconnect(vio->lp); | ||
| 101 | } | 129 | } |
| 102 | } | 130 | } |
| 103 | EXPORT_SYMBOL(vio_link_state_change); | 131 | EXPORT_SYMBOL(vio_link_state_change); |
| @@ -396,6 +424,8 @@ static int process_dreg_info(struct vio_driver_state *vio, | |||
| 396 | if (vio->dr_state & VIO_DR_STATE_RXREG) | 424 | if (vio->dr_state & VIO_DR_STATE_RXREG) |
| 397 | goto send_nack; | 425 | goto send_nack; |
| 398 | 426 | ||
| 427 | BUG_ON(vio->desc_buf); | ||
| 428 | |||
| 399 | vio->desc_buf = kzalloc(pkt->descr_size, GFP_ATOMIC); | 429 | vio->desc_buf = kzalloc(pkt->descr_size, GFP_ATOMIC); |
| 400 | if (!vio->desc_buf) | 430 | if (!vio->desc_buf) |
| 401 | goto send_nack; | 431 | goto send_nack; |
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 */ |
diff --git a/include/asm-sparc64/io.h b/include/asm-sparc64/io.h index ad595b679842..9565a892801e 100644 --- a/include/asm-sparc64/io.h +++ b/include/asm-sparc64/io.h | |||
| @@ -14,11 +14,6 @@ | |||
| 14 | #define __SLOW_DOWN_IO do { } while (0) | 14 | #define __SLOW_DOWN_IO do { } while (0) |
| 15 | #define SLOW_DOWN_IO do { } while (0) | 15 | #define SLOW_DOWN_IO do { } while (0) |
| 16 | 16 | ||
| 17 | extern unsigned long virt_to_bus_not_defined_use_pci_map(volatile void *addr); | ||
| 18 | #define virt_to_bus virt_to_bus_not_defined_use_pci_map | ||
| 19 | extern unsigned long bus_to_virt_not_defined_use_pci_map(volatile void *addr); | ||
| 20 | #define bus_to_virt bus_to_virt_not_defined_use_pci_map | ||
| 21 | |||
| 22 | /* BIO layer definitions. */ | 17 | /* BIO layer definitions. */ |
| 23 | extern unsigned long kern_base, kern_size; | 18 | extern unsigned long kern_base, kern_size; |
| 24 | #define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT) | 19 | #define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT) |
diff --git a/include/asm-sparc64/mdesc.h b/include/asm-sparc64/mdesc.h index e97c43133752..1acc7272e537 100644 --- a/include/asm-sparc64/mdesc.h +++ b/include/asm-sparc64/mdesc.h | |||
| @@ -61,6 +61,16 @@ extern u64 mdesc_arc_target(struct mdesc_handle *hp, u64 arc); | |||
| 61 | 61 | ||
| 62 | extern void mdesc_update(void); | 62 | extern void mdesc_update(void); |
| 63 | 63 | ||
| 64 | struct mdesc_notifier_client { | ||
| 65 | void (*add)(struct mdesc_handle *handle, u64 node); | ||
| 66 | void (*remove)(struct mdesc_handle *handle, u64 node); | ||
| 67 | |||
| 68 | const char *node_name; | ||
| 69 | struct mdesc_notifier_client *next; | ||
| 70 | }; | ||
| 71 | |||
| 72 | extern void mdesc_register_notifier(struct mdesc_notifier_client *client); | ||
| 73 | |||
| 64 | extern void mdesc_fill_in_cpu_data(cpumask_t mask); | 74 | extern void mdesc_fill_in_cpu_data(cpumask_t mask); |
| 65 | 75 | ||
| 66 | extern void sun4v_mdesc_init(void); | 76 | extern void sun4v_mdesc_init(void); |
diff --git a/include/asm-sparc64/vio.h b/include/asm-sparc64/vio.h index 83c96422e9d6..c0a8d4ed5bcb 100644 --- a/include/asm-sparc64/vio.h +++ b/include/asm-sparc64/vio.h | |||
| @@ -264,7 +264,7 @@ static inline u32 vio_dring_avail(struct vio_dring_state *dr, | |||
| 264 | ((dr->prod - dr->cons) & (ring_size - 1))); | 264 | ((dr->prod - dr->cons) & (ring_size - 1))); |
| 265 | } | 265 | } |
| 266 | 266 | ||
| 267 | #define VIO_MAX_TYPE_LEN 64 | 267 | #define VIO_MAX_TYPE_LEN 32 |
| 268 | #define VIO_MAX_COMPAT_LEN 64 | 268 | #define VIO_MAX_COMPAT_LEN 64 |
| 269 | 269 | ||
| 270 | struct vio_dev { | 270 | struct vio_dev { |
