| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: usbnet.c,v 1.23 2019/08/23 04:29:28 mrg Exp $ */ | | 1 | /* $NetBSD: usbnet.c,v 1.24 2019/08/28 06:07:21 mrg Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 2019 Matthew R. Green | | 4 | * Copyright (c) 2019 Matthew R. Green |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * Redistribution and use in source and binary forms, with or without | | 7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions | | 8 | * modification, are permitted provided that the following conditions |
9 | * are met: | | 9 | * are met: |
10 | * 1. Redistributions of source code must retain the above copyright | | 10 | * 1. Redistributions of source code must retain the above copyright |
11 | * notice, this list of conditions and the following disclaimer. | | 11 | * notice, this list of conditions and the following disclaimer. |
12 | * 2. Redistributions in binary form must reproduce the above copyright | | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the | | 13 | * notice, this list of conditions and the following disclaimer in the |
14 | * documentation and/or other materials provided with the distribution. | | 14 | * documentation and/or other materials provided with the distribution. |
| @@ -23,27 +23,27 @@ | | | @@ -23,27 +23,27 @@ |
23 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | | 23 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
24 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED | | 24 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
25 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | | 25 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
26 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 26 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
27 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | | 27 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
28 | * SUCH DAMAGE. | | 28 | * SUCH DAMAGE. |
29 | */ | | 29 | */ |
30 | | | 30 | |
31 | /* | | 31 | /* |
32 | * Common code shared between USB network drivers. | | 32 | * Common code shared between USB network drivers. |
33 | */ | | 33 | */ |
34 | | | 34 | |
35 | #include <sys/cdefs.h> | | 35 | #include <sys/cdefs.h> |
36 | __KERNEL_RCSID(0, "$NetBSD: usbnet.c,v 1.23 2019/08/23 04:29:28 mrg Exp $"); | | 36 | __KERNEL_RCSID(0, "$NetBSD: usbnet.c,v 1.24 2019/08/28 06:07:21 mrg Exp $"); |
37 | | | 37 | |
38 | #include <sys/param.h> | | 38 | #include <sys/param.h> |
39 | #include <sys/kernel.h> | | 39 | #include <sys/kernel.h> |
40 | #include <sys/kmem.h> | | 40 | #include <sys/kmem.h> |
41 | #include <sys/module.h> | | 41 | #include <sys/module.h> |
42 | #include <sys/atomic.h> | | 42 | #include <sys/atomic.h> |
43 | | | 43 | |
44 | #include <dev/usb/usbnet.h> | | 44 | #include <dev/usb/usbnet.h> |
45 | #include <dev/usb/usbhist.h> | | 45 | #include <dev/usb/usbhist.h> |
46 | | | 46 | |
47 | struct usbnet_cdata { | | 47 | struct usbnet_cdata { |
48 | struct usbnet_chain *uncd_tx_chain; | | 48 | struct usbnet_chain *uncd_tx_chain; |
49 | struct usbnet_chain *uncd_rx_chain; | | 49 | struct usbnet_chain *uncd_rx_chain; |
| @@ -1447,38 +1447,39 @@ usbnet_attach_ifp(struct usbnet *un, | | | @@ -1447,38 +1447,39 @@ usbnet_attach_ifp(struct usbnet *un, |
1447 | ifp->if_softc = un; | | 1447 | ifp->if_softc = un; |
1448 | | | 1448 | |
1449 | usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, un->un_udev, un->un_dev); | | 1449 | usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, un->un_udev, un->un_dev); |
1450 | | | 1450 | |
1451 | if (!pmf_device_register(un->un_dev, NULL, NULL)) | | 1451 | if (!pmf_device_register(un->un_dev, NULL, NULL)) |
1452 | aprint_error_dev(un->un_dev, "couldn't establish power handler\n"); | | 1452 | aprint_error_dev(un->un_dev, "couldn't establish power handler\n"); |
1453 | } | | 1453 | } |
1454 | | | 1454 | |
1455 | int | | 1455 | int |
1456 | usbnet_detach(device_t self, int flags) | | 1456 | usbnet_detach(device_t self, int flags) |
1457 | { | | 1457 | { |
1458 | USBNETHIST_FUNC(); USBNETHIST_CALLED(); | | 1458 | USBNETHIST_FUNC(); USBNETHIST_CALLED(); |
1459 | struct usbnet * const un = device_private(self); | | 1459 | struct usbnet * const un = device_private(self); |
| | | 1460 | struct usbnet_private * const unp = un->un_pri; |
| | | 1461 | |
| | | 1462 | /* Detached before attached finished, so just bail out. */ |
| | | 1463 | if (unp == NULL || !unp->unp_attached) |
| | | 1464 | return 0; |
| | | 1465 | |
1460 | struct ifnet * const ifp = usbnet_ifp(un); | | 1466 | struct ifnet * const ifp = usbnet_ifp(un); |
1461 | struct mii_data * const mii = usbnet_mii(un); | | 1467 | struct mii_data * const mii = usbnet_mii(un); |
1462 | struct usbnet_private * const unp = un->un_pri; | | | |
1463 | | | 1468 | |
1464 | mutex_enter(&unp->unp_lock); | | 1469 | mutex_enter(&unp->unp_lock); |
1465 | unp->unp_dying = true; | | 1470 | unp->unp_dying = true; |
1466 | mutex_exit(&unp->unp_lock); | | 1471 | mutex_exit(&unp->unp_lock); |
1467 | | | 1472 | |
1468 | /* Detached before attached finished, so just bail out. */ | | | |
1469 | if (!unp->unp_attached) | | | |
1470 | return 0; | | | |
1471 | | | | |
1472 | callout_halt(&unp->unp_stat_ch, NULL); | | 1473 | callout_halt(&unp->unp_stat_ch, NULL); |
1473 | usb_rem_task_wait(un->un_udev, &unp->unp_ticktask, USB_TASKQ_DRIVER, NULL); | | 1474 | usb_rem_task_wait(un->un_udev, &unp->unp_ticktask, USB_TASKQ_DRIVER, NULL); |
1474 | | | 1475 | |
1475 | if (ifp->if_flags & IFF_RUNNING) { | | 1476 | if (ifp->if_flags & IFF_RUNNING) { |
1476 | IFNET_LOCK(ifp); | | 1477 | IFNET_LOCK(ifp); |
1477 | usbnet_stop_ifp(ifp, 1); | | 1478 | usbnet_stop_ifp(ifp, 1); |
1478 | IFNET_UNLOCK(ifp); | | 1479 | IFNET_UNLOCK(ifp); |
1479 | } | | 1480 | } |
1480 | | | 1481 | |
1481 | mutex_enter(&unp->unp_lock); | | 1482 | mutex_enter(&unp->unp_lock); |
1482 | unp->unp_refcnt--; | | 1483 | unp->unp_refcnt--; |
1483 | while (unp->unp_refcnt > 0) { | | 1484 | while (unp->unp_refcnt > 0) { |
1484 | /* Wait for processes to go away */ | | 1485 | /* Wait for processes to go away */ |