| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: if_xennet_xenbus.c,v 1.63 2014/08/10 16:44:35 tls Exp $ */ | | 1 | /* $NetBSD: if_xennet_xenbus.c,v 1.63.2.1 2016/03/06 18:52:06 martin 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 | * |
| @@ -75,27 +75,27 @@ | | | @@ -75,27 +75,27 @@ |
75 | * Purpose is to process the packets received from the outside. RX buffers | | 75 | * Purpose is to process the packets received from the outside. RX buffers |
76 | * are pre-allocated through xennet_alloc_rx_buffer(), during xennet autoconf | | 76 | * are pre-allocated through xennet_alloc_rx_buffer(), during xennet autoconf |
77 | * attach. During pre-allocation, frontend pushes requests in the I/O ring, in | | 77 | * attach. During pre-allocation, frontend pushes requests in the I/O ring, in |
78 | * preparation for incoming packets from backend. | | 78 | * preparation for incoming packets from backend. |
79 | * When RX packets need to be processed, backend takes the requests previously | | 79 | * When RX packets need to be processed, backend takes the requests previously |
80 | * offered by frontend and pushes the associated responses inside the I/O ring. | | 80 | * offered by frontend and pushes the associated responses inside the I/O ring. |
81 | * When done, it notifies frontend through an event notification, which will | | 81 | * When done, it notifies frontend through an event notification, which will |
82 | * asynchronously call xennet_handler() in frontend. | | 82 | * asynchronously call xennet_handler() in frontend. |
83 | * xennet_handler() processes the responses, generates the associated mbuf, and | | 83 | * xennet_handler() processes the responses, generates the associated mbuf, and |
84 | * passes it to the MI layer for further processing. | | 84 | * passes it to the MI layer for further processing. |
85 | */ | | 85 | */ |
86 | | | 86 | |
87 | #include <sys/cdefs.h> | | 87 | #include <sys/cdefs.h> |
88 | __KERNEL_RCSID(0, "$NetBSD: if_xennet_xenbus.c,v 1.63 2014/08/10 16:44:35 tls Exp $"); | | 88 | __KERNEL_RCSID(0, "$NetBSD: if_xennet_xenbus.c,v 1.63.2.1 2016/03/06 18:52:06 martin Exp $"); |
89 | | | 89 | |
90 | #include "opt_xen.h" | | 90 | #include "opt_xen.h" |
91 | #include "opt_nfs_boot.h" | | 91 | #include "opt_nfs_boot.h" |
92 | | | 92 | |
93 | #include <sys/param.h> | | 93 | #include <sys/param.h> |
94 | #include <sys/device.h> | | 94 | #include <sys/device.h> |
95 | #include <sys/conf.h> | | 95 | #include <sys/conf.h> |
96 | #include <sys/kernel.h> | | 96 | #include <sys/kernel.h> |
97 | #include <sys/proc.h> | | 97 | #include <sys/proc.h> |
98 | #include <sys/systm.h> | | 98 | #include <sys/systm.h> |
99 | #include <sys/intr.h> | | 99 | #include <sys/intr.h> |
100 | #include <sys/rnd.h> | | 100 | #include <sys/rnd.h> |
101 | | | 101 | |
| @@ -411,26 +411,27 @@ xennet_xenbus_attach(device_t parent, de | | | @@ -411,26 +411,27 @@ xennet_xenbus_attach(device_t parent, de |
411 | } | | 411 | } |
412 | | | 412 | |
413 | static int | | 413 | static int |
414 | xennet_xenbus_detach(device_t self, int flags) | | 414 | xennet_xenbus_detach(device_t self, int flags) |
415 | { | | 415 | { |
416 | struct xennet_xenbus_softc *sc = device_private(self); | | 416 | struct xennet_xenbus_softc *sc = device_private(self); |
417 | struct ifnet *ifp = &sc->sc_ethercom.ec_if; | | 417 | struct ifnet *ifp = &sc->sc_ethercom.ec_if; |
418 | int s0, s1; | | 418 | int s0, s1; |
419 | RING_IDX i; | | 419 | RING_IDX i; |
420 | | | 420 | |
421 | DPRINTF(("%s: xennet_xenbus_detach\n", device_xname(self))); | | 421 | DPRINTF(("%s: xennet_xenbus_detach\n", device_xname(self))); |
422 | s0 = splnet(); | | 422 | s0 = splnet(); |
423 | xennet_stop(ifp, 1); | | 423 | xennet_stop(ifp, 1); |
| | | 424 | event_remove_handler(sc->sc_evtchn, &xennet_handler, sc); |
424 | /* wait for pending TX to complete, and collect pending RX packets */ | | 425 | /* wait for pending TX to complete, and collect pending RX packets */ |
425 | xennet_handler(sc); | | 426 | xennet_handler(sc); |
426 | while (sc->sc_tx_ring.sring->rsp_prod != sc->sc_tx_ring.rsp_cons) { | | 427 | while (sc->sc_tx_ring.sring->rsp_prod != sc->sc_tx_ring.rsp_cons) { |
427 | tsleep(xennet_xenbus_detach, PRIBIO, "xnet_detach", hz/2); | | 428 | tsleep(xennet_xenbus_detach, PRIBIO, "xnet_detach", hz/2); |
428 | xennet_handler(sc); | | 429 | xennet_handler(sc); |
429 | } | | 430 | } |
430 | xennet_free_rx_buffer(sc); | | 431 | xennet_free_rx_buffer(sc); |
431 | | | 432 | |
432 | s1 = splvm(); | | 433 | s1 = splvm(); |
433 | for (i = 0; i < NET_RX_RING_SIZE; i++) { | | 434 | for (i = 0; i < NET_RX_RING_SIZE; i++) { |
434 | struct xennet_rxreq *rxreq = &sc->sc_rxreqs[i]; | | 435 | struct xennet_rxreq *rxreq = &sc->sc_rxreqs[i]; |
435 | uvm_km_free(kernel_map, rxreq->rxreq_va, PAGE_SIZE, | | 436 | uvm_km_free(kernel_map, rxreq->rxreq_va, PAGE_SIZE, |
436 | UVM_KMF_WIRED); | | 437 | UVM_KMF_WIRED); |
| @@ -446,27 +447,26 @@ xennet_xenbus_detach(device_t self, int | | | @@ -446,27 +447,26 @@ xennet_xenbus_detach(device_t self, int |
446 | while (xengnt_status(sc->sc_tx_ring_gntref)) { | | 447 | while (xengnt_status(sc->sc_tx_ring_gntref)) { |
447 | tsleep(xennet_xenbus_detach, PRIBIO, "xnet_txref", hz/2); | | 448 | tsleep(xennet_xenbus_detach, PRIBIO, "xnet_txref", hz/2); |
448 | } | | 449 | } |
449 | xengnt_revoke_access(sc->sc_tx_ring_gntref); | | 450 | xengnt_revoke_access(sc->sc_tx_ring_gntref); |
450 | uvm_km_free(kernel_map, (vaddr_t)sc->sc_tx_ring.sring, PAGE_SIZE, | | 451 | uvm_km_free(kernel_map, (vaddr_t)sc->sc_tx_ring.sring, PAGE_SIZE, |
451 | UVM_KMF_WIRED); | | 452 | UVM_KMF_WIRED); |
452 | while (xengnt_status(sc->sc_rx_ring_gntref)) { | | 453 | while (xengnt_status(sc->sc_rx_ring_gntref)) { |
453 | tsleep(xennet_xenbus_detach, PRIBIO, "xnet_rxref", hz/2); | | 454 | tsleep(xennet_xenbus_detach, PRIBIO, "xnet_rxref", hz/2); |
454 | } | | 455 | } |
455 | xengnt_revoke_access(sc->sc_rx_ring_gntref); | | 456 | xengnt_revoke_access(sc->sc_rx_ring_gntref); |
456 | uvm_km_free(kernel_map, (vaddr_t)sc->sc_rx_ring.sring, PAGE_SIZE, | | 457 | uvm_km_free(kernel_map, (vaddr_t)sc->sc_rx_ring.sring, PAGE_SIZE, |
457 | UVM_KMF_WIRED); | | 458 | UVM_KMF_WIRED); |
458 | softint_disestablish(sc->sc_softintr); | | 459 | softint_disestablish(sc->sc_softintr); |
459 | event_remove_handler(sc->sc_evtchn, &xennet_handler, sc); | | | |
460 | splx(s0); | | 460 | splx(s0); |
461 | | | 461 | |
462 | pmf_device_deregister(self); | | 462 | pmf_device_deregister(self); |
463 | | | 463 | |
464 | DPRINTF(("%s: xennet_xenbus_detach done\n", device_xname(self))); | | 464 | DPRINTF(("%s: xennet_xenbus_detach done\n", device_xname(self))); |
465 | return 0; | | 465 | return 0; |
466 | } | | 466 | } |
467 | | | 467 | |
468 | static bool | | 468 | static bool |
469 | xennet_xenbus_resume(device_t dev, const pmf_qual_t *qual) | | 469 | xennet_xenbus_resume(device_t dev, const pmf_qual_t *qual) |
470 | { | | 470 | { |
471 | struct xennet_xenbus_softc *sc = device_private(dev); | | 471 | struct xennet_xenbus_softc *sc = device_private(dev); |
472 | int error; | | 472 | int error; |