| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: xennetback_xenbus.c,v 1.40 2011/04/06 23:51:55 jym Exp $ */ | | 1 | /* $NetBSD: xennetback_xenbus.c,v 1.41 2011/04/20 20:32:38 jym Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 2006 Manuel Bouyer. | | 4 | * Copyright (c) 2006 Manuel Bouyer. |
5 | * | | 5 | * |
6 | * Redistribution and use in source and binary forms, with or without | | 6 | * Redistribution and use in source and binary forms, with or without |
7 | * modification, are permitted provided that the following conditions | | 7 | * modification, are permitted provided that the following conditions |
8 | * are met: | | 8 | * are met: |
9 | * 1. Redistributions of source code must retain the above copyright | | 9 | * 1. Redistributions of source code must retain the above copyright |
10 | * notice, this list of conditions and the following disclaimer. | | 10 | * notice, this list of conditions and the following disclaimer. |
11 | * 2. Redistributions in binary form must reproduce the above copyright | | 11 | * 2. Redistributions in binary form must reproduce the above copyright |
12 | * notice, this list of conditions and the following disclaimer in the | | 12 | * notice, this list of conditions and the following disclaimer in the |
13 | * documentation and/or other materials provided with the distribution. | | 13 | * documentation and/or other materials provided with the distribution. |
14 | * | | 14 | * |
| @@ -423,26 +423,27 @@ xennetback_xenbus_destroy(void *arg) | | | @@ -423,26 +423,27 @@ xennetback_xenbus_destroy(void *arg) |
423 | free(xneti, M_DEVBUF); | | 423 | free(xneti, M_DEVBUF); |
424 | return 0; | | 424 | return 0; |
425 | } | | 425 | } |
426 | | | 426 | |
427 | static void | | 427 | static void |
428 | xennetback_frontend_changed(void *arg, XenbusState new_state) | | 428 | xennetback_frontend_changed(void *arg, XenbusState new_state) |
429 | { | | 429 | { |
430 | struct xnetback_instance *xneti = arg; | | 430 | struct xnetback_instance *xneti = arg; |
431 | struct xenbus_device *xbusd = xneti->xni_xbusd; | | 431 | struct xenbus_device *xbusd = xneti->xni_xbusd; |
432 | int err; | | 432 | int err; |
433 | netif_tx_sring_t *tx_ring; | | 433 | netif_tx_sring_t *tx_ring; |
434 | netif_rx_sring_t *rx_ring; | | 434 | netif_rx_sring_t *rx_ring; |
435 | struct gnttab_map_grant_ref op; | | 435 | struct gnttab_map_grant_ref op; |
| | | 436 | struct gnttab_unmap_grant_ref uop; |
436 | evtchn_op_t evop; | | 437 | evtchn_op_t evop; |
437 | u_long tx_ring_ref, rx_ring_ref; | | 438 | u_long tx_ring_ref, rx_ring_ref; |
438 | u_long revtchn, rx_copy; | | 439 | u_long revtchn, rx_copy; |
439 | | | 440 | |
440 | XENPRINTF(("%s: new state %d\n", xneti->xni_if.if_xname, new_state)); | | 441 | XENPRINTF(("%s: new state %d\n", xneti->xni_if.if_xname, new_state)); |
441 | switch(new_state) { | | 442 | switch(new_state) { |
442 | case XenbusStateInitialising: | | 443 | case XenbusStateInitialising: |
443 | case XenbusStateInitialised: | | 444 | case XenbusStateInitialised: |
444 | break; | | 445 | break; |
445 | | | 446 | |
446 | case XenbusStateConnected: | | 447 | case XenbusStateConnected: |
447 | /* read comunication informations */ | | 448 | /* read comunication informations */ |
448 | err = xenbus_read_ul(NULL, xbusd->xbusd_otherend, | | 449 | err = xenbus_read_ul(NULL, xbusd->xbusd_otherend, |
| @@ -528,27 +529,27 @@ xennetback_frontend_changed(void *arg, X | | | @@ -528,27 +529,27 @@ xennetback_frontend_changed(void *arg, X |
528 | xneti->xni_if.if_xname, err, op.status); | | 529 | xneti->xni_if.if_xname, err, op.status); |
529 | goto err2; | | 530 | goto err2; |
530 | } | | 531 | } |
531 | xneti->xni_rx_ring_handle = op.handle; | | 532 | xneti->xni_rx_ring_handle = op.handle; |
532 | BACK_RING_INIT(&xneti->xni_txring, tx_ring, PAGE_SIZE); | | 533 | BACK_RING_INIT(&xneti->xni_txring, tx_ring, PAGE_SIZE); |
533 | BACK_RING_INIT(&xneti->xni_rxring, rx_ring, PAGE_SIZE); | | 534 | BACK_RING_INIT(&xneti->xni_rxring, rx_ring, PAGE_SIZE); |
534 | evop.cmd = EVTCHNOP_bind_interdomain; | | 535 | evop.cmd = EVTCHNOP_bind_interdomain; |
535 | evop.u.bind_interdomain.remote_dom = xneti->xni_domid; | | 536 | evop.u.bind_interdomain.remote_dom = xneti->xni_domid; |
536 | evop.u.bind_interdomain.remote_port = revtchn; | | 537 | evop.u.bind_interdomain.remote_port = revtchn; |
537 | err = HYPERVISOR_event_channel_op(&evop); | | 538 | err = HYPERVISOR_event_channel_op(&evop); |
538 | if (err) { | | 539 | if (err) { |
539 | printf("%s: can't get event channel: %d\n", | | 540 | printf("%s: can't get event channel: %d\n", |
540 | xneti->xni_if.if_xname, err); | | 541 | xneti->xni_if.if_xname, err); |
541 | goto err2; | | 542 | goto err3; |
542 | } | | 543 | } |
543 | xneti->xni_evtchn = evop.u.bind_interdomain.local_port; | | 544 | xneti->xni_evtchn = evop.u.bind_interdomain.local_port; |
544 | xen_wmb(); | | 545 | xen_wmb(); |
545 | xneti->xni_status = CONNECTED; | | 546 | xneti->xni_status = CONNECTED; |
546 | xenbus_switch_state(xbusd, NULL, XenbusStateConnected); | | 547 | xenbus_switch_state(xbusd, NULL, XenbusStateConnected); |
547 | xen_wmb(); | | 548 | xen_wmb(); |
548 | event_set_handler(xneti->xni_evtchn, xennetback_evthandler, | | 549 | event_set_handler(xneti->xni_evtchn, xennetback_evthandler, |
549 | xneti, IPL_NET, xneti->xni_if.if_xname); | | 550 | xneti, IPL_NET, xneti->xni_if.if_xname); |
550 | xennetback_ifinit(&xneti->xni_if); | | 551 | xennetback_ifinit(&xneti->xni_if); |
551 | hypervisor_enable_event(xneti->xni_evtchn); | | 552 | hypervisor_enable_event(xneti->xni_evtchn); |
552 | hypervisor_notify_via_evtchn(xneti->xni_evtchn); | | 553 | hypervisor_notify_via_evtchn(xneti->xni_evtchn); |
553 | break; | | 554 | break; |
554 | | | 555 | |
| @@ -560,26 +561,46 @@ xennetback_frontend_changed(void *arg, X | | | @@ -560,26 +561,46 @@ xennetback_frontend_changed(void *arg, X |
560 | break; | | 561 | break; |
561 | | | 562 | |
562 | case XenbusStateClosed: | | 563 | case XenbusStateClosed: |
563 | /* otherend_changed() should handle it for us */ | | 564 | /* otherend_changed() should handle it for us */ |
564 | panic("xennetback_frontend_changed: closed\n"); | | 565 | panic("xennetback_frontend_changed: closed\n"); |
565 | case XenbusStateUnknown: | | 566 | case XenbusStateUnknown: |
566 | case XenbusStateInitWait: | | 567 | case XenbusStateInitWait: |
567 | default: | | 568 | default: |
568 | aprint_error("%s: invalid frontend state %d\n", | | 569 | aprint_error("%s: invalid frontend state %d\n", |
569 | xneti->xni_if.if_xname, new_state); | | 570 | xneti->xni_if.if_xname, new_state); |
570 | break; | | 571 | break; |
571 | } | | 572 | } |
572 | return; | | 573 | return; |
| | | 574 | |
| | | 575 | err3: |
| | | 576 | uop.dev_bus_addr = 0; |
| | | 577 | |
| | | 578 | uop.host_addr = xneti->xni_rx_ring_va; |
| | | 579 | uop.handle = xneti->xni_rx_ring_handle; |
| | | 580 | err = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, |
| | | 581 | &uop, 1); |
| | | 582 | if (err) |
| | | 583 | aprint_error_ifnet(&xneti->xni_if, |
| | | 584 | "unmap_grant_ref failed: %d\n", err); |
| | | 585 | |
| | | 586 | uop.host_addr = xneti->xni_tx_ring_va; |
| | | 587 | uop.handle = xneti->xni_tx_ring_handle; |
| | | 588 | err = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, |
| | | 589 | &uop, 1); |
| | | 590 | if (err) |
| | | 591 | aprint_error_ifnet(&xneti->xni_if, |
| | | 592 | "unmap_grant_ref failed: %d\n", err); |
| | | 593 | |
573 | err2: | | 594 | err2: |
574 | uvm_km_free(kernel_map, xneti->xni_rx_ring_va, | | 595 | uvm_km_free(kernel_map, xneti->xni_rx_ring_va, |
575 | PAGE_SIZE, UVM_KMF_VAONLY); | | 596 | PAGE_SIZE, UVM_KMF_VAONLY); |
576 | err1: | | 597 | err1: |
577 | uvm_km_free(kernel_map, xneti->xni_tx_ring_va, | | 598 | uvm_km_free(kernel_map, xneti->xni_tx_ring_va, |
578 | PAGE_SIZE, UVM_KMF_VAONLY); | | 599 | PAGE_SIZE, UVM_KMF_VAONLY); |
579 | } | | 600 | } |
580 | | | 601 | |
581 | /* lookup a xneti based on domain id and interface handle */ | | 602 | /* lookup a xneti based on domain id and interface handle */ |
582 | static struct xnetback_instance * | | 603 | static struct xnetback_instance * |
583 | xnetif_lookup(domid_t dom , uint32_t handle) | | 604 | xnetif_lookup(domid_t dom , uint32_t handle) |
584 | { | | 605 | { |
585 | struct xnetback_instance *xneti; | | 606 | struct xnetback_instance *xneti; |