Module Name: src Committed By: mrg Date: Sat Aug 10 02:17:36 UTC 2019
Modified Files: src/sys/dev/usb: if_axe.c if_axen.c if_cdce.c if_smsc.c if_udav.c if_ure.c if_urndis.c usbnet.c usbnet.h src/sys/sys: param.h Log Message: reduce the scope of struct usbnet: - move a large number of members internal to usbnet.c's new "struct usbnet_private". - provide accessors for a few of these - move struct usbnet_cdata into usbnet.c as well, but move bufsz, list count, and xfer flags back out into struct usbnet, and have them set as part of the setup efore usbnet_attach() - split the intr pipe parts into their own structure - move all the main usbnet*lock* code into usbnet.c too usbnet_attach() goes down to 2 args, and the inputs needed are now the full contents of 'struct usbnet' besides the driver owned 'un_flags' and usbnet owned 'un_pri'. welcome netbsd 9.99.6. To generate a diff of this commit: cvs rdiff -u -r1.108 -r1.109 src/sys/dev/usb/if_axe.c cvs rdiff -u -r1.58 -r1.59 src/sys/dev/usb/if_axen.c cvs rdiff -u -r1.60 -r1.61 src/sys/dev/usb/if_cdce.c cvs rdiff -u -r1.50 -r1.51 src/sys/dev/usb/if_smsc.c cvs rdiff -u -r1.64 -r1.65 src/sys/dev/usb/if_udav.c cvs rdiff -u -r1.20 -r1.21 src/sys/dev/usb/if_ure.c cvs rdiff -u -r1.26 -r1.27 src/sys/dev/usb/if_urndis.c cvs rdiff -u -r1.10 -r1.11 src/sys/dev/usb/usbnet.c cvs rdiff -u -r1.8 -r1.9 src/sys/dev/usb/usbnet.h cvs rdiff -u -r1.604 -r1.605 src/sys/sys/param.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/usb/if_axe.c diff -u src/sys/dev/usb/if_axe.c:1.108 src/sys/dev/usb/if_axe.c:1.109 --- src/sys/dev/usb/if_axe.c:1.108 Fri Aug 9 02:52:59 2019 +++ src/sys/dev/usb/if_axe.c Sat Aug 10 02:17:36 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: if_axe.c,v 1.108 2019/08/09 02:52:59 mrg Exp $ */ +/* $NetBSD: if_axe.c,v 1.109 2019/08/10 02:17:36 mrg Exp $ */ /* $OpenBSD: if_axe.c,v 1.137 2016/04/13 11:03:37 mpi Exp $ */ /* @@ -87,7 +87,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_axe.c,v 1.108 2019/08/09 02:52:59 mrg Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_axe.c,v 1.109 2019/08/10 02:17:36 mrg Exp $"); #ifdef _KERNEL_OPT #include "opt_usb.h" @@ -385,7 +385,7 @@ axe_mii_statchg_cb(struct ifnet *ifp) return; val = 0; - un->un_link = false; + usbnet_set_link(un, false); if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) != 0) { val |= AXE_MEDIA_FULL_DUPLEX; if (AXE_IS_178_FAMILY(un)) { @@ -404,14 +404,14 @@ axe_mii_statchg_cb(struct ifnet *ifp) switch (IFM_SUBTYPE(mii->mii_media_active)) { case IFM_1000_T: val |= AXE_178_MEDIA_GMII | AXE_178_MEDIA_ENCK; - un->un_link = true; + usbnet_set_link(un, true); break; case IFM_100_TX: val |= AXE_178_MEDIA_100TX; - un->un_link = true; + usbnet_set_link(un, true); break; case IFM_10_T: - un->un_link = true; + usbnet_set_link(un, true); break; } } @@ -886,6 +886,10 @@ axe_attach(device_t parent, device_t sel un->un_udev = dev; un->un_sc = sc; un->un_ops = &axe_ops; + un->un_rx_xfer_flags = USBD_SHORT_XFER_OK; + un->un_tx_xfer_flags = USBD_FORCE_SHORT_XFER; + un->un_rx_list_cnt = AXE_RX_LIST_CNT; + un->un_tx_list_cnt = AXE_TX_LIST_CNT; err = usbd_set_config_no(dev, AXE_CONFIG_NO, 1); if (err) { @@ -910,6 +914,7 @@ axe_attach(device_t parent, device_t sel AXE_178_MAX_BUFSZ : AXE_178_MIN_BUFSZ; else bufsz = AXE_172_BUFSZ; + un->un_rx_bufsz = un->un_tx_bufsz = bufsz; un->un_ed[USBNET_ENDPT_RX] = 0; un->un_ed[USBNET_ENDPT_TX] = 0; @@ -937,8 +942,7 @@ axe_attach(device_t parent, device_t sel } /* Set these up now for axe_cmd(). */ - usbnet_attach(un, "axedet", AXE_RX_LIST_CNT, AXE_TX_LIST_CNT, - USBD_SHORT_XFER_OK, USBD_FORCE_SHORT_XFER, bufsz, bufsz); + usbnet_attach(un, "axedet"); /* We need the PHYID for init dance in some cases */ usbnet_lock_mii(un); Index: src/sys/dev/usb/if_axen.c diff -u src/sys/dev/usb/if_axen.c:1.58 src/sys/dev/usb/if_axen.c:1.59 --- src/sys/dev/usb/if_axen.c:1.58 Fri Aug 9 02:52:59 2019 +++ src/sys/dev/usb/if_axen.c Sat Aug 10 02:17:36 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: if_axen.c,v 1.58 2019/08/09 02:52:59 mrg Exp $ */ +/* $NetBSD: if_axen.c,v 1.59 2019/08/10 02:17:36 mrg Exp $ */ /* $OpenBSD: if_axen.c,v 1.3 2013/10/21 10:10:22 yuo Exp $ */ /* @@ -23,7 +23,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_axen.c,v 1.58 2019/08/09 02:52:59 mrg Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_axen.c,v 1.59 2019/08/10 02:17:36 mrg Exp $"); #ifdef _KERNEL_OPT #include "opt_usb.h" @@ -169,16 +169,16 @@ axen_mii_statchg(struct ifnet *ifp) if (usbnet_isdying(un)) return; - un->un_link = false; + usbnet_set_link(un, false); if ((mii->mii_media_status & (IFM_ACTIVE | IFM_AVALID)) == (IFM_ACTIVE | IFM_AVALID)) { switch (IFM_SUBTYPE(mii->mii_media_active)) { case IFM_10_T: case IFM_100_TX: - un->un_link = true; + usbnet_set_link(un, true); break; case IFM_1000_T: - un->un_link = true; + usbnet_set_link(un, true); break; default: break; @@ -186,7 +186,7 @@ axen_mii_statchg(struct ifnet *ifp) } /* Lost link, do nothing. */ - if (!un->un_link) + if (!usbnet_havelink(un)) return; val = 0; @@ -599,7 +599,6 @@ axen_attach(device_t parent, device_t se usb_interface_descriptor_t *id; usb_endpoint_descriptor_t *ed; char *devinfop; - unsigned rx_bufsz, tx_bufsz; uint16_t axen_flags; int i; @@ -613,6 +612,10 @@ axen_attach(device_t parent, device_t se un->un_udev = dev; un->un_sc = un; un->un_ops = &axen_ops; + un->un_rx_xfer_flags = USBD_SHORT_XFER_OK; + un->un_tx_xfer_flags = USBD_FORCE_SHORT_XFER; + un->un_rx_list_cnt = AXEN_RX_LIST_CNT; + un->un_tx_list_cnt = AXEN_TX_LIST_CNT; err = usbd_set_config_no(dev, AXEN_CONFIG_NO, 1); if (err) { @@ -632,17 +635,17 @@ axen_attach(device_t parent, device_t se /* decide on what our bufsize will be */ switch (dev->ud_speed) { case USB_SPEED_SUPER: - rx_bufsz = AXEN_BUFSZ_SS * 1024; + un->un_rx_bufsz = AXEN_BUFSZ_SS * 1024; break; case USB_SPEED_HIGH: - rx_bufsz = AXEN_BUFSZ_HS * 1024; + un->un_rx_bufsz = AXEN_BUFSZ_HS * 1024; break; default: - rx_bufsz = AXEN_BUFSZ_LS * 1024; + un->un_rx_bufsz = AXEN_BUFSZ_LS * 1024; break; } - tx_bufsz = IP_MAXPACKET + ETHER_HDR_LEN + ETHER_CRC_LEN + - ETHER_VLAN_ENCAP_LEN + sizeof(struct axen_sframe_hdr); + un->un_tx_bufsz = IP_MAXPACKET + ETHER_HDR_LEN + ETHER_CRC_LEN + + ETHER_VLAN_ENCAP_LEN + sizeof(struct axen_sframe_hdr); /* Find endpoints. */ id = usbd_get_interface_descriptor(un->un_iface); @@ -667,9 +670,7 @@ axen_attach(device_t parent, device_t se } /* Set these up now for axen_cmd(). */ - usbnet_attach(un, "axendet", AXEN_RX_LIST_CNT, AXEN_TX_LIST_CNT, - USBD_SHORT_XFER_OK, USBD_FORCE_SHORT_XFER, - rx_bufsz, tx_bufsz); + usbnet_attach(un, "axendet"); un->un_phyno = AXEN_PHY_ID; DPRINTF(("%s: phyno %d\n", device_xname(self), un->un_phyno)); @@ -876,7 +877,7 @@ axen_tx_prepare(struct usbnet *un, struc } length = m->m_pkthdr.len + sizeof(hdr); - KASSERT(length <= un->un_cdata.uncd_tx_bufsz); + KASSERT(length <= un->un_tx_bufsz); hdr.plen = htole32(m->m_pkthdr.len); Index: src/sys/dev/usb/if_cdce.c diff -u src/sys/dev/usb/if_cdce.c:1.60 src/sys/dev/usb/if_cdce.c:1.61 --- src/sys/dev/usb/if_cdce.c:1.60 Fri Aug 9 02:52:59 2019 +++ src/sys/dev/usb/if_cdce.c Sat Aug 10 02:17:36 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: if_cdce.c,v 1.60 2019/08/09 02:52:59 mrg Exp $ */ +/* $NetBSD: if_cdce.c,v 1.61 2019/08/10 02:17:36 mrg Exp $ */ /* * Copyright (c) 1997, 1998, 1999, 2000-2003 Bill Paul <wp...@windriver.com> @@ -40,7 +40,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_cdce.c,v 1.60 2019/08/09 02:52:59 mrg Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_cdce.c,v 1.61 2019/08/10 02:17:36 mrg Exp $"); #include <sys/param.h> #include <sys/kernel.h> @@ -133,6 +133,12 @@ cdce_attach(device_t parent, device_t se un->un_udev = dev; un->un_sc = un; un->un_ops = &cdce_ops; + un->un_rx_xfer_flags = USBD_SHORT_XFER_OK; + un->un_tx_xfer_flags = USBD_FORCE_SHORT_XFER; + un->un_rx_list_cnt = CDCE_RX_LIST_CNT; + un->un_tx_list_cnt = CDCE_TX_LIST_CNT; + un->un_rx_bufsz = CDCE_BUFSZ; + un->un_tx_bufsz = CDCE_BUFSZ; t = cdce_lookup(uiaa->uiaa_vendor, uiaa->uiaa_product); if (t) @@ -242,9 +248,7 @@ cdce_attach(device_t parent, device_t se un->un_eaddr[5] = (uint8_t)(device_unit(un->un_dev)); } - usbnet_attach(un, "cdcedet", CDCE_RX_LIST_CNT, CDCE_TX_LIST_CNT, - USBD_SHORT_XFER_OK, USBD_FORCE_SHORT_XFER, - CDCE_BUFSZ, CDCE_BUFSZ); + usbnet_attach(un, "cdcedet"); usbnet_attach_ifp(un, false, IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST, 0, 0); } @@ -261,8 +265,7 @@ cdce_init(struct ifnet *ifp) else { usbnet_stop(un, ifp, 1); rv = usbnet_init_rx_tx(un); - if (rv == 0) - un->un_link = true; + usbnet_set_link(un, rv == 0); } usbnet_unlock(un); Index: src/sys/dev/usb/if_smsc.c diff -u src/sys/dev/usb/if_smsc.c:1.50 src/sys/dev/usb/if_smsc.c:1.51 --- src/sys/dev/usb/if_smsc.c:1.50 Fri Aug 9 07:54:05 2019 +++ src/sys/dev/usb/if_smsc.c Sat Aug 10 02:17:36 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: if_smsc.c,v 1.50 2019/08/09 07:54:05 skrll Exp $ */ +/* $NetBSD: if_smsc.c,v 1.51 2019/08/10 02:17:36 mrg Exp $ */ /* $OpenBSD: if_smsc.c,v 1.4 2012/09/27 12:38:11 jsg Exp $ */ /* $FreeBSD: src/sys/dev/usb/net/if_smsc.c,v 1.1 2012/08/15 04:03:55 gonzo Exp $ */ @@ -61,7 +61,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_smsc.c,v 1.50 2019/08/09 07:54:05 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_smsc.c,v 1.51 2019/08/10 02:17:36 mrg Exp $"); #ifdef _KERNEL_OPT #include "opt_usb.h" @@ -319,13 +319,13 @@ smsc_miibus_statchg(struct ifnet *ifp) uint32_t flow; uint32_t afc_cfg; - un->un_link = false; + usbnet_set_link(un, false); if ((mii->mii_media_status & (IFM_ACTIVE | IFM_AVALID)) == (IFM_ACTIVE | IFM_AVALID)) { switch (IFM_SUBTYPE(mii->mii_media_active)) { case IFM_10_T: case IFM_100_TX: - un->un_link = true; + usbnet_set_link(un, true); break; case IFM_1000_T: /* Gigabit ethernet not supported by chipset */ @@ -336,7 +336,7 @@ smsc_miibus_statchg(struct ifnet *ifp) } /* Lost link, do nothing. */ - if (!un->un_link) + if (!usbnet_havelink(un)) return; usbnet_lock_mii(un); @@ -801,6 +801,10 @@ smsc_attach(device_t parent, device_t se un->un_udev = dev; un->un_sc = sc; un->un_ops = &smsc_ops; + un->un_rx_xfer_flags = USBD_SHORT_XFER_OK; + un->un_tx_xfer_flags = USBD_FORCE_SHORT_XFER; + un->un_rx_list_cnt = SMSC_RX_LIST_CNT; + un->un_tx_list_cnt = SMSC_TX_LIST_CNT; devinfop = usbd_devinfo_alloc(un->un_udev, 0); aprint_normal_dev(self, "%s\n", devinfop); @@ -827,6 +831,8 @@ smsc_attach(device_t parent, device_t se } else { bufsz = SMSC_MIN_BUFSZ; } + un->un_rx_bufsz = bufsz; + un->un_tx_bufsz = bufsz; /* Find endpoints. */ for (i = 0; i < id->bNumEndpoints; i++) { @@ -849,8 +855,7 @@ smsc_attach(device_t parent, device_t se } } - usbnet_attach(un, "smscdet", SMSC_RX_LIST_CNT, SMSC_TX_LIST_CNT, - USBD_SHORT_XFER_OK, USBD_FORCE_SHORT_XFER, bufsz, bufsz); + usbnet_attach(un, "smscdet"); #ifdef notyet /* Index: src/sys/dev/usb/if_udav.c diff -u src/sys/dev/usb/if_udav.c:1.64 src/sys/dev/usb/if_udav.c:1.65 --- src/sys/dev/usb/if_udav.c:1.64 Fri Aug 9 06:44:42 2019 +++ src/sys/dev/usb/if_udav.c Sat Aug 10 02:17:36 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: if_udav.c,v 1.64 2019/08/09 06:44:42 mrg Exp $ */ +/* $NetBSD: if_udav.c,v 1.65 2019/08/10 02:17:36 mrg Exp $ */ /* $nabe: if_udav.c,v 1.3 2003/08/21 16:57:19 nabe Exp $ */ /* @@ -45,7 +45,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_udav.c,v 1.64 2019/08/09 06:44:42 mrg Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_udav.c,v 1.65 2019/08/10 02:17:36 mrg Exp $"); #ifdef _KERNEL_OPT #include "opt_usb.h" @@ -180,6 +180,12 @@ udav_attach(device_t parent, device_t se un->un_udev = dev; un->un_sc = un; un->un_ops = &udav_ops; + un->un_rx_xfer_flags = USBD_SHORT_XFER_OK; + un->un_tx_xfer_flags = USBD_FORCE_SHORT_XFER; + un->un_rx_list_cnt = UDAV_RX_LIST_CNT; + un->un_tx_list_cnt = UDAV_TX_LIST_CNT; + un->un_rx_bufsz = UDAV_BUFSZ; + un->un_tx_bufsz = UDAV_BUFSZ; /* Move the device into the configured state. */ err = usbd_set_config_no(dev, UDAV_CONFIG_NO, 1); /* idx 0 */ @@ -237,9 +243,7 @@ udav_attach(device_t parent, device_t se // /* reset the adapter */ // udav_reset(un); - usbnet_attach(un, "udavdet", UDAV_RX_LIST_CNT, UDAV_TX_LIST_CNT, - USBD_SHORT_XFER_OK, USBD_FORCE_SHORT_XFER, - UDAV_BUFSZ, UDAV_BUFSZ); + usbnet_attach(un, "udavdet"); /* Get Ethernet Address */ usbnet_lock_mii(un); @@ -252,7 +256,7 @@ udav_attach(device_t parent, device_t se bool have_mii = !ISSET(un->un_flags, UDAV_NO_PHY); if (!have_mii) - un->un_link = 1; + usbnet_set_link(un, true); /* initialize interface information */ usbnet_attach_ifp(un, have_mii, @@ -867,12 +871,12 @@ udav_mii_statchg(struct ifnet *ifp) if (usbnet_isdying(un)) return; - un->un_link = false; + usbnet_set_link(un, false); if (mii->mii_media_status & IFM_ACTIVE && IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) { DPRINTF(("%s: %s: got link\n", device_xname(un->un_dev), __func__)); - un->un_link = true; + usbnet_set_link(un, true); } } Index: src/sys/dev/usb/if_ure.c diff -u src/sys/dev/usb/if_ure.c:1.20 src/sys/dev/usb/if_ure.c:1.21 --- src/sys/dev/usb/if_ure.c:1.20 Fri Aug 9 02:52:59 2019 +++ src/sys/dev/usb/if_ure.c Sat Aug 10 02:17:36 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: if_ure.c,v 1.20 2019/08/09 02:52:59 mrg Exp $ */ +/* $NetBSD: if_ure.c,v 1.21 2019/08/10 02:17:36 mrg Exp $ */ /* $OpenBSD: if_ure.c,v 1.10 2018/11/02 21:32:30 jcs Exp $ */ /*- @@ -30,7 +30,7 @@ /* RealTek RTL8152/RTL8153 10/100/Gigabit USB Ethernet device */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_ure.c,v 1.20 2019/08/09 02:52:59 mrg Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_ure.c,v 1.21 2019/08/10 02:17:36 mrg Exp $"); #ifdef _KERNEL_OPT #include "opt_usb.h" @@ -302,18 +302,18 @@ ure_miibus_statchg(struct ifnet *ifp) if (usbnet_isdying(un)) return; - un->un_link = false; + usbnet_set_link(un, false); if ((mii->mii_media_status & (IFM_ACTIVE | IFM_AVALID)) == (IFM_ACTIVE | IFM_AVALID)) { switch (IFM_SUBTYPE(mii->mii_media_active)) { case IFM_10_T: case IFM_100_TX: - un->un_link = true; + usbnet_set_link(un, true); break; case IFM_1000_T: if ((un->un_flags & URE_FLAG_8152) != 0) break; - un->un_link = true; + usbnet_set_link(un, true); break; default: break; @@ -855,6 +855,12 @@ ure_attach(device_t parent, device_t sel un->un_udev = dev; un->un_sc = un; un->un_ops = &ure_ops; + un->un_rx_xfer_flags = USBD_SHORT_XFER_OK; + un->un_tx_xfer_flags = USBD_FORCE_SHORT_XFER; + un->un_rx_list_cnt = URE_RX_LIST_CNT; + un->un_tx_list_cnt = URE_TX_LIST_CNT; + un->un_rx_bufsz = URE_BUFSZ; + un->un_tx_bufsz = URE_BUFSZ; #define URE_CONFIG_NO 1 /* XXX */ error = usbd_set_config_no(dev, URE_CONFIG_NO, 1); @@ -892,9 +898,7 @@ ure_attach(device_t parent, device_t sel } /* Set these up now for ure_ctl(). */ - usbnet_attach(un, "uredet", URE_RX_LIST_CNT, URE_TX_LIST_CNT, - USBD_SHORT_XFER_OK, USBD_FORCE_SHORT_XFER, - URE_BUFSZ, URE_BUFSZ); + usbnet_attach(un, "uredet"); un->un_phyno = 0; Index: src/sys/dev/usb/if_urndis.c diff -u src/sys/dev/usb/if_urndis.c:1.26 src/sys/dev/usb/if_urndis.c:1.27 --- src/sys/dev/usb/if_urndis.c:1.26 Fri Aug 9 06:38:39 2019 +++ src/sys/dev/usb/if_urndis.c Sat Aug 10 02:17:36 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: if_urndis.c,v 1.26 2019/08/09 06:38:39 mrg Exp $ */ +/* $NetBSD: if_urndis.c,v 1.27 2019/08/10 02:17:36 mrg Exp $ */ /* $OpenBSD: if_urndis.c,v 1.31 2011/07/03 15:47:17 matthew Exp $ */ /* @@ -21,7 +21,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_urndis.c,v 1.26 2019/08/09 06:38:39 mrg Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_urndis.c,v 1.27 2019/08/10 02:17:36 mrg Exp $"); #ifdef _KERNEL_OPT #include "opt_usb.h" @@ -130,7 +130,7 @@ urndis_ctrl_send(struct usbnet *un, void struct urndis_softc *sc = usbnet_softc(un); usbd_status err; - if (un->un_dying) + if (usbnet_isdying(un)) return(0); err = urndis_ctrl_msg(un, UT_WRITE_CLASS_INTERFACE, UR_GET_STATUS, @@ -150,7 +150,7 @@ urndis_ctrl_recv(struct usbnet *un) char *buf; usbd_status err; - if (un->un_dying) + if (usbnet_isdying(un)) return(0); buf = kmem_alloc(URNDIS_RESPONSE_LEN, KM_SLEEP); @@ -866,13 +866,12 @@ urndis_init_un(struct ifnet *ifp, struct return EIO; usbnet_lock(un); - if (un->un_dying) + if (usbnet_isdying(un)) err = EIO; else { usbnet_stop(un, ifp, 1); err = usbnet_init_rx_tx(un); - if (err == 0) - un->un_link = true; + usbnet_set_link(un, err == 0); } usbnet_unlock(un); @@ -943,6 +942,12 @@ urndis_attach(device_t parent, device_t un->un_udev = dev; un->un_sc = sc; un->un_ops = &urndis_ops; + un->un_rx_xfer_flags = USBD_SHORT_XFER_OK; + un->un_tx_xfer_flags = USBD_FORCE_SHORT_XFER; + un->un_rx_list_cnt = RNDIS_RX_LIST_CNT; + un->un_tx_list_cnt = RNDIS_TX_LIST_CNT; + un->un_rx_bufsz = RNDIS_BUFSZ; + un->un_tx_bufsz = RNDIS_BUFSZ; iface_ctl = uiaa->uiaa_iface; un->un_iface = uiaa->uiaa_iface; @@ -1044,9 +1049,7 @@ urndis_attach(device_t parent, device_t ifp->if_watchdog = urndis_watchdog; #endif - usbnet_attach(un, "urndisdet", RNDIS_RX_LIST_CNT, RNDIS_TX_LIST_CNT, - USBD_SHORT_XFER_OK, USBD_FORCE_SHORT_XFER, - RNDIS_BUFSZ, RNDIS_BUFSZ); + usbnet_attach(un, "urndisdet"); urndis_init_un(ifp, un); Index: src/sys/dev/usb/usbnet.c diff -u src/sys/dev/usb/usbnet.c:1.10 src/sys/dev/usb/usbnet.c:1.11 --- src/sys/dev/usb/usbnet.c:1.10 Fri Aug 9 01:17:33 2019 +++ src/sys/dev/usb/usbnet.c Sat Aug 10 02:17:36 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: usbnet.c,v 1.10 2019/08/09 01:17:33 mrg Exp $ */ +/* $NetBSD: usbnet.c,v 1.11 2019/08/10 02:17:36 mrg Exp $ */ /* * Copyright (c) 2019 Matthew R. Green @@ -33,7 +33,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: usbnet.c,v 1.10 2019/08/09 01:17:33 mrg Exp $"); +__KERNEL_RCSID(0, "$NetBSD: usbnet.c,v 1.11 2019/08/10 02:17:36 mrg Exp $"); #include <sys/param.h> #include <sys/kernel.h> @@ -43,6 +43,55 @@ __KERNEL_RCSID(0, "$NetBSD: usbnet.c,v 1 #include <dev/usb/usbnet.h> #include <dev/usb/usbhist.h> +struct usbnet_cdata { + struct usbnet_chain *uncd_tx_chain; + struct usbnet_chain *uncd_rx_chain; + + int uncd_tx_prod; + int uncd_tx_cnt; + int uncd_rx_cnt; +}; + +struct usbnet_private { + /* + * - unp_lock protects most of the structure, and the public one + * - unp_miilock must be held to access this device's MII bus + * - unp_rxlock protects the rx path and its data + * - unp_txlock protects the tx path and its data + * - unp_detachcv handles detach vs open references + */ + kmutex_t unp_lock; + kmutex_t unp_miilock; + kmutex_t unp_rxlock; + kmutex_t unp_txlock; + kcondvar_t unp_detachcv; + + struct usbnet_cdata unp_cdata; + + struct ethercom unp_ec; + struct mii_data unp_mii; + struct usb_task unp_ticktask; + struct callout unp_stat_ch; + struct usbd_pipe *unp_ep[USBNET_ENDPT_MAX]; + + bool unp_dying; + bool unp_stopping; + bool unp_attached; + bool unp_link; + + int unp_refcnt; + int unp_timer; + int unp_if_flags; + + krndsource_t unp_rndsrc; + + struct timeval unp_rx_notice; + struct timeval unp_tx_notice; + struct timeval unp_intr_notice; +}; + +#define un_cdata(un) (&(un)->un_pri->unp_cdata) + static int usbnet_modcmd(modcmd_t, void *); #ifdef USB_DEBUG @@ -190,10 +239,10 @@ usbnet_enqueue(struct usbnet * const un, int csum_flags, uint32_t csum_data, int mbuf_flags) { USBNETHIST_FUNC(); USBNETHIST_CALLED(); - struct ifnet *ifp = &un->un_ec.ec_if; + struct ifnet * const ifp = usbnet_ifp(un); struct mbuf *m; - KASSERT(mutex_owned(&un->un_rxlock)); + KASSERT(mutex_owned(&un->un_pri->unp_rxlock)); m = usbnet_newbuf(); if (m == NULL) { @@ -219,7 +268,7 @@ usbnet_input(struct usbnet * const un, u struct ifnet * const ifp = usbnet_ifp(un); struct mbuf *m; - KASSERT(mutex_owned(&un->un_rxlock)); + KASSERT(mutex_owned(&un->un_pri->unp_rxlock)); m = usbnet_newbuf(); if (m == NULL) { @@ -243,75 +292,76 @@ static void usbnet_rxeof(struct usbd_xfer *xfer, void *priv, usbd_status status) { USBNETHIST_FUNC(); USBNETHIST_CALLED(); - struct usbnet_chain *c = priv; + struct usbnet_chain * const c = priv; struct usbnet * const un = c->unc_un; - struct usbnet_cdata *cd = &un->un_cdata; + struct usbnet_private * const unp = un->un_pri; struct ifnet * const ifp = usbnet_ifp(un); uint32_t total_len; - mutex_enter(&un->un_rxlock); + mutex_enter(&unp->unp_rxlock); - if (un->un_dying || un->un_stopping || + if (unp->unp_dying || unp->unp_stopping || status == USBD_INVAL || status == USBD_NOT_STARTED || status == USBD_CANCELLED || !(ifp->if_flags & IFF_RUNNING)) goto out; if (status != USBD_NORMAL_COMPLETION) { - if (usbd_ratecheck(&un->un_rx_notice)) + if (usbd_ratecheck(&unp->unp_rx_notice)) aprint_error_dev(un->un_dev, "usb errors on rx: %s\n", usbd_errstr(status)); if (status == USBD_STALLED) - usbd_clear_endpoint_stall_async(un->un_ep[USBNET_ENDPT_RX]); + usbd_clear_endpoint_stall_async(unp->unp_ep[USBNET_ENDPT_RX]); goto done; } usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL); - if (total_len > cd->uncd_rx_bufsz) { + if (total_len > un->un_rx_bufsz) { aprint_error_dev(un->un_dev, "rxeof: too large transfer (%u > %u)\n", - total_len, cd->uncd_rx_bufsz); + total_len, un->un_rx_bufsz); goto done; } uno_rx_loop(un, xfer, c, total_len); - KASSERT(mutex_owned(&un->un_rxlock)); + KASSERT(mutex_owned(&unp->unp_rxlock)); done: - if (un->un_dying || un->un_stopping) + if (unp->unp_dying || unp->unp_stopping) goto out; - mutex_exit(&un->un_rxlock); + mutex_exit(&unp->unp_rxlock); /* Setup new transfer. */ - usbd_setup_xfer(xfer, c, c->unc_buf, cd->uncd_rx_bufsz, - cd->uncd_rx_xfer_flags, USBD_NO_TIMEOUT, usbnet_rxeof); + usbd_setup_xfer(xfer, c, c->unc_buf, un->un_rx_bufsz, + un->un_rx_xfer_flags, USBD_NO_TIMEOUT, usbnet_rxeof); usbd_transfer(xfer); return; out: - mutex_exit(&un->un_rxlock); + mutex_exit(&unp->unp_rxlock); } static void usbnet_txeof(struct usbd_xfer *xfer, void *priv, usbd_status status) { USBNETHIST_FUNC(); USBNETHIST_CALLED(); - struct usbnet_chain *c = priv; + struct usbnet_chain * const c = priv; struct usbnet * const un = c->unc_un; - struct usbnet_cdata *cd = &un->un_cdata; + struct usbnet_cdata * const cd = un_cdata(un); + struct usbnet_private * const unp = un->un_pri; struct ifnet * const ifp = usbnet_ifp(un); - mutex_enter(&un->un_txlock); - if (un->un_stopping || un->un_dying) { - mutex_exit(&un->un_txlock); + mutex_enter(&unp->unp_txlock); + if (unp->unp_stopping || unp->unp_dying) { + mutex_exit(&unp->unp_txlock); return; } KASSERT(cd->uncd_tx_cnt > 0); cd->uncd_tx_cnt--; - un->un_timer = 0; + unp->unp_timer = 0; switch (status) { case USBD_NOT_STARTED: @@ -325,39 +375,41 @@ usbnet_txeof(struct usbd_xfer *xfer, voi default: ifp->if_oerrors++; - if (usbd_ratecheck(&un->un_tx_notice)) + if (usbd_ratecheck(&unp->unp_tx_notice)) aprint_error_dev(un->un_dev, "usb error on tx: %s\n", usbd_errstr(status)); if (status == USBD_STALLED) - usbd_clear_endpoint_stall_async(un->un_ep[USBNET_ENDPT_TX]); + usbd_clear_endpoint_stall_async(unp->unp_ep[USBNET_ENDPT_TX]); break; } - mutex_exit(&un->un_txlock); + mutex_exit(&unp->unp_txlock); if (status == USBD_NORMAL_COMPLETION && !IFQ_IS_EMPTY(&ifp->if_snd)) (*ifp->if_start)(ifp); } static void -usbnet_intr(struct usbd_xfer *xfer, void *priv, usbd_status status) +usbnet_pipe_intr(struct usbd_xfer *xfer, void *priv, usbd_status status) { USBNETHIST_FUNC(); USBNETHIST_CALLED(); - struct usbnet *un = priv; - struct ifnet *ifp = usbnet_ifp(un); + struct usbnet * const un = priv; + struct usbnet_private * const unp = un->un_pri; + struct usbnet_intr * const uni = un->un_intr; + struct ifnet * const ifp = usbnet_ifp(un); - if (un->un_dying || un->un_stopping || + if (uni == NULL || unp->unp_dying || unp->unp_stopping || status == USBD_INVAL || status == USBD_NOT_STARTED || status == USBD_CANCELLED || !(ifp->if_flags & IFF_RUNNING)) return; if (status != USBD_NORMAL_COMPLETION) { - if (usbd_ratecheck(&un->un_intr_notice)) { + if (usbd_ratecheck(&unp->unp_intr_notice)) { aprint_error_dev(un->un_dev, "usb error on intr: %s\n", usbd_errstr(status)); } if (status == USBD_STALLED) - usbd_clear_endpoint_stall_async(un->un_ep[USBNET_ENDPT_INTR]); + usbd_clear_endpoint_stall_async(unp->unp_ep[USBNET_ENDPT_INTR]); return; } @@ -369,19 +421,20 @@ usbnet_start_locked(struct ifnet *ifp) { USBNETHIST_FUNC(); USBNETHIST_CALLED(); struct usbnet * const un = ifp->if_softc; - struct usbnet_cdata *cd = &un->un_cdata; + struct usbnet_cdata * const cd = un_cdata(un); + struct usbnet_private * const unp = un->un_pri; struct mbuf *m; unsigned length; int idx; - KASSERT(mutex_owned(&un->un_txlock)); - KASSERT(cd->uncd_tx_cnt <= cd->uncd_tx_list_cnt); + KASSERT(mutex_owned(&unp->unp_txlock)); + KASSERT(cd->uncd_tx_cnt <= un->un_tx_list_cnt); - if (!un->un_link || (ifp->if_flags & IFF_RUNNING) == 0) + if (!unp->unp_link || (ifp->if_flags & IFF_RUNNING) == 0) return; idx = cd->uncd_tx_prod; - while (cd->uncd_tx_cnt < cd->uncd_tx_list_cnt) { + while (cd->uncd_tx_cnt < un->un_tx_list_cnt) { IFQ_POLL(&ifp->if_snd, m); if (m == NULL) break; @@ -400,7 +453,7 @@ usbnet_start_locked(struct ifnet *ifp) } usbd_setup_xfer(c->unc_xfer, c, c->unc_buf, length, - cd->uncd_tx_xfer_flags, 10000, usbnet_txeof); + un->un_tx_xfer_flags, 10000, usbnet_txeof); /* Transmit */ usbd_status err = usbd_transfer(c->unc_xfer); @@ -418,7 +471,7 @@ usbnet_start_locked(struct ifnet *ifp) bpf_mtap(ifp, m, BPF_D_OUT); m_freem(m); - idx = (idx + 1) % cd->uncd_tx_list_cnt; + idx = (idx + 1) % un->un_tx_list_cnt; cd->uncd_tx_cnt++; } cd->uncd_tx_prod = idx; @@ -426,18 +479,19 @@ usbnet_start_locked(struct ifnet *ifp) /* * Set a timeout in case the chip goes out to lunch. */ - un->un_timer = 5; + unp->unp_timer = 5; } static void usbnet_start(struct ifnet *ifp) { struct usbnet * const un = ifp->if_softc; + struct usbnet_private * const unp = un->un_pri; - mutex_enter(&un->un_txlock); - if (!un->un_stopping) + mutex_enter(&unp->unp_txlock); + if (!unp->unp_stopping) usbnet_start_locked(ifp); - mutex_exit(&un->un_txlock); + mutex_exit(&unp->unp_txlock); } /* @@ -449,26 +503,26 @@ usbnet_start(struct ifnet *ifp) /* Start of common RX functions */ static size_t -usbnet_rx_list_size(struct usbnet_cdata *cd) +usbnet_rx_list_size(struct usbnet_cdata *cd, struct usbnet *un) { - return sizeof(*cd->uncd_rx_chain) * cd->uncd_rx_list_cnt; + return sizeof(*cd->uncd_rx_chain) * un->un_rx_list_cnt; } static void usbnet_rx_list_alloc(struct usbnet *un) { - struct usbnet_cdata *cd = &un->un_cdata; + struct usbnet_cdata * const cd = un_cdata(un); - cd->uncd_rx_chain = kmem_zalloc(usbnet_rx_list_size(cd), KM_SLEEP); + cd->uncd_rx_chain = kmem_zalloc(usbnet_rx_list_size(cd, un), KM_SLEEP); } static void usbnet_rx_list_free(struct usbnet *un) { - struct usbnet_cdata *cd = &un->un_cdata; + struct usbnet_cdata * const cd = un_cdata(un); if (cd->uncd_rx_chain) { - kmem_free(cd->uncd_rx_chain, usbnet_rx_list_size(cd)); + kmem_free(cd->uncd_rx_chain, usbnet_rx_list_size(cd, un)); cd->uncd_rx_chain = NULL; } } @@ -476,15 +530,16 @@ usbnet_rx_list_free(struct usbnet *un) static int usbnet_rx_list_init(struct usbnet *un) { - struct usbnet_cdata *cd = &un->un_cdata; + struct usbnet_cdata * const cd = un_cdata(un); + struct usbnet_private * const unp = un->un_pri; - for (size_t i = 0; i < cd->uncd_rx_list_cnt; i++) { + for (size_t i = 0; i < un->un_rx_list_cnt; i++) { struct usbnet_chain *c = &cd->uncd_rx_chain[i]; c->unc_un = un; if (c->unc_xfer == NULL) { - int err = usbd_create_xfer(un->un_ep[USBNET_ENDPT_RX], - cd->uncd_rx_bufsz, cd->uncd_rx_xfer_flags, 0, + int err = usbd_create_xfer(unp->unp_ep[USBNET_ENDPT_RX], + un->un_rx_bufsz, un->un_rx_xfer_flags, 0, &c->unc_xfer); if (err) return err; @@ -498,9 +553,9 @@ usbnet_rx_list_init(struct usbnet *un) static void usbnet_rx_list_fini(struct usbnet *un) { - struct usbnet_cdata *cd = &un->un_cdata; + struct usbnet_cdata * const cd = un_cdata(un); - for (size_t i = 0; i < cd->uncd_rx_list_cnt; i++) { + for (size_t i = 0; i < un->un_rx_list_cnt; i++) { struct usbnet_chain *c = &cd->uncd_rx_chain[i]; if (c->unc_xfer != NULL) { @@ -516,47 +571,48 @@ usbnet_rx_list_fini(struct usbnet *un) static void usbnet_rx_start_pipes(struct usbnet *un, usbd_callback cb) { - struct usbnet_cdata *cd = &un->un_cdata; + struct usbnet_cdata * const cd = un_cdata(un); + struct usbnet_private * const unp = un->un_pri; - mutex_enter(&un->un_rxlock); - mutex_enter(&un->un_txlock); - un->un_stopping = false; + mutex_enter(&unp->unp_rxlock); + mutex_enter(&unp->unp_txlock); + unp->unp_stopping = false; - for (size_t i = 0; i < cd->uncd_rx_list_cnt; i++) { + for (size_t i = 0; i < un->un_rx_list_cnt; i++) { struct usbnet_chain *c = &cd->uncd_rx_chain[i]; - usbd_setup_xfer(c->unc_xfer, c, c->unc_buf, cd->uncd_rx_bufsz, - cd->uncd_rx_xfer_flags, USBD_NO_TIMEOUT, cb); + usbd_setup_xfer(c->unc_xfer, c, c->unc_buf, un->un_rx_bufsz, + un->un_rx_xfer_flags, USBD_NO_TIMEOUT, cb); usbd_transfer(c->unc_xfer); } - mutex_exit(&un->un_txlock); - mutex_exit(&un->un_rxlock); + mutex_exit(&unp->unp_txlock); + mutex_exit(&unp->unp_rxlock); } /* Start of common TX functions */ static size_t -usbnet_tx_list_size(struct usbnet_cdata *cd) +usbnet_tx_list_size(struct usbnet_cdata *cd, struct usbnet *un) { - return sizeof(*cd->uncd_tx_chain) * cd->uncd_tx_list_cnt; + return sizeof(*cd->uncd_tx_chain) * un->un_tx_list_cnt; } static void usbnet_tx_list_alloc(struct usbnet *un) { - struct usbnet_cdata *cd = &un->un_cdata; + struct usbnet_cdata * const cd = un_cdata(un); - cd->uncd_tx_chain = kmem_zalloc(usbnet_tx_list_size(cd), KM_SLEEP); + cd->uncd_tx_chain = kmem_zalloc(usbnet_tx_list_size(cd, un), KM_SLEEP); } static void usbnet_tx_list_free(struct usbnet *un) { - struct usbnet_cdata *cd = &un->un_cdata; + struct usbnet_cdata * const cd = un_cdata(un); if (cd->uncd_tx_chain) { - kmem_free(cd->uncd_tx_chain, usbnet_tx_list_size(cd)); + kmem_free(cd->uncd_tx_chain, usbnet_tx_list_size(cd, un)); cd->uncd_tx_chain = NULL; } } @@ -564,15 +620,16 @@ usbnet_tx_list_free(struct usbnet *un) static int usbnet_tx_list_init(struct usbnet *un) { - struct usbnet_cdata *cd = &un->un_cdata; + struct usbnet_cdata * const cd = un_cdata(un); + struct usbnet_private * const unp = un->un_pri; - for (size_t i = 0; i < cd->uncd_tx_list_cnt; i++) { + for (size_t i = 0; i < un->un_tx_list_cnt; i++) { struct usbnet_chain *c = &cd->uncd_tx_chain[i]; c->unc_un = un; if (c->unc_xfer == NULL) { - int err = usbd_create_xfer(un->un_ep[USBNET_ENDPT_TX], - cd->uncd_tx_bufsz, cd->uncd_tx_xfer_flags, 0, + int err = usbd_create_xfer(unp->unp_ep[USBNET_ENDPT_TX], + un->un_tx_bufsz, un->un_tx_xfer_flags, 0, &c->unc_xfer); if (err) return err; @@ -586,9 +643,9 @@ usbnet_tx_list_init(struct usbnet *un) static void usbnet_tx_list_fini(struct usbnet *un) { - struct usbnet_cdata *cd = &un->un_cdata; + struct usbnet_cdata * const cd = un_cdata(un); - for (size_t i = 0; i < cd->uncd_tx_list_cnt; i++) { + for (size_t i = 0; i < un->un_tx_list_cnt; i++) { struct usbnet_chain *c = &cd->uncd_tx_chain[i]; if (c->unc_xfer != NULL) { @@ -606,34 +663,39 @@ usbnet_tx_list_fini(struct usbnet *un) static void usbnet_ep_close_pipes(struct usbnet *un) { - for (size_t i = 0; i < __arraycount(un->un_ep); i++) { - if (un->un_ep[i] == NULL) + struct usbnet_private * const unp = un->un_pri; + + for (size_t i = 0; i < __arraycount(unp->unp_ep); i++) { + if (unp->unp_ep[i] == NULL) continue; - usbd_status err = usbd_close_pipe(un->un_ep[i]); + usbd_status err = usbd_close_pipe(unp->unp_ep[i]); if (err) aprint_error_dev(un->un_dev, "close pipe %zu: %s\n", i, usbd_errstr(err)); - un->un_ep[i] = NULL; + unp->unp_ep[i] = NULL; } } static usbd_status usbnet_ep_open_pipes(struct usbnet *un) { - for (size_t i = 0; i < __arraycount(un->un_ep); i++) { + struct usbnet_intr * const uni = un->un_intr; + struct usbnet_private * const unp = un->un_pri; + + for (size_t i = 0; i < __arraycount(unp->unp_ep); i++) { usbd_status err; if (un->un_ed[i] == 0) continue; - if (i == USBNET_ENDPT_INTR && un->un_intr_buf) { + if (i == USBNET_ENDPT_INTR && uni) { err = usbd_open_pipe_intr(un->un_iface, un->un_ed[i], - USBD_EXCLUSIVE_USE | USBD_MPSAFE, &un->un_ep[i], un, - un->un_intr_buf, un->un_intr_bufsz, usbnet_intr, - un->un_intr_interval); + USBD_EXCLUSIVE_USE | USBD_MPSAFE, &unp->unp_ep[i], un, + uni->uni_buf, uni->uni_bufsz, usbnet_pipe_intr, + uni->uni_interval); } else { err = usbd_open_pipe(un->un_iface, un->un_ed[i], - USBD_EXCLUSIVE_USE | USBD_MPSAFE, &un->un_ep[i]); + USBD_EXCLUSIVE_USE | USBD_MPSAFE, &unp->unp_ep[i]); } if (err) { usbnet_ep_close_pipes(un); @@ -647,10 +709,12 @@ usbnet_ep_open_pipes(struct usbnet *un) static usbd_status usbnet_ep_stop_pipes(struct usbnet *un) { - for (size_t i = 0; i < __arraycount(un->un_ep); i++) { - if (un->un_ep[i] == NULL) + struct usbnet_private * const unp = un->un_pri; + + for (size_t i = 0; i < __arraycount(unp->unp_ep); i++) { + if (unp->unp_ep[i] == NULL) continue; - usbd_status err = usbd_abort_pipe(un->un_ep[i]); + usbd_status err = usbd_abort_pipe(unp->unp_ep[i]); if (err) return err; } @@ -662,16 +726,17 @@ int usbnet_init_rx_tx(struct usbnet * const un) { USBNETHIST_FUNC(); USBNETHIST_CALLED(); + struct usbnet_private * const unp = un->un_pri; struct ifnet * const ifp = usbnet_ifp(un); usbd_status err; int error = 0; usbnet_isowned(un); - if (un->un_dying) { + if (unp->unp_dying) { return EIO; } - un->un_refcnt++; + unp->unp_refcnt++; /* Open RX and TX pipes. */ err = usbnet_ep_open_pipes(un); @@ -703,7 +768,7 @@ usbnet_init_rx_tx(struct usbnet * const KASSERT(ifp->if_softc == NULL || IFNET_LOCKED(ifp)); ifp->if_flags |= IFF_RUNNING; - callout_schedule(&un->un_stat_ch, hz); + callout_schedule(&unp->unp_stat_ch, hz); out: if (error) { @@ -711,8 +776,8 @@ out: usbnet_tx_list_fini(un); usbnet_ep_close_pipes(un); } - if (--un->un_refcnt < 0) - cv_broadcast(&un->un_detachcv); + if (--unp->unp_refcnt < 0) + cv_broadcast(&unp->unp_detachcv); usbnet_isowned(un); @@ -728,56 +793,71 @@ out: void usbnet_lock_mii(struct usbnet *un) { + struct usbnet_private * const unp = un->un_pri; - mutex_enter(&un->un_lock); - un->un_refcnt++; - mutex_exit(&un->un_lock); + mutex_enter(&unp->unp_lock); + unp->unp_refcnt++; + mutex_exit(&unp->unp_lock); - mutex_enter(&un->un_miilock); + mutex_enter(&unp->unp_miilock); } void usbnet_lock_mii_un_locked(struct usbnet *un) { - KASSERT(mutex_owned(&un->un_lock)); + struct usbnet_private * const unp = un->un_pri; + + KASSERT(mutex_owned(&unp->unp_lock)); - un->un_refcnt++; - mutex_enter(&un->un_miilock); + unp->unp_refcnt++; + mutex_enter(&unp->unp_miilock); } void usbnet_unlock_mii(struct usbnet *un) { + struct usbnet_private * const unp = un->un_pri; - mutex_exit(&un->un_miilock); - mutex_enter(&un->un_lock); - if (--un->un_refcnt < 0) - cv_broadcast(&un->un_detachcv); - mutex_exit(&un->un_lock); + mutex_exit(&unp->unp_miilock); + mutex_enter(&unp->unp_lock); + if (--unp->unp_refcnt < 0) + cv_broadcast(&unp->unp_detachcv); + mutex_exit(&unp->unp_lock); } void usbnet_unlock_mii_un_locked(struct usbnet *un) { - KASSERT(mutex_owned(&un->un_lock)); + struct usbnet_private * const unp = un->un_pri; - mutex_exit(&un->un_miilock); - if (--un->un_refcnt < 0) - cv_broadcast(&un->un_detachcv); + KASSERT(mutex_owned(&unp->unp_lock)); + + mutex_exit(&unp->unp_miilock); + if (--unp->unp_refcnt < 0) + cv_broadcast(&unp->unp_detachcv); +} + +kmutex_t * +usbnet_mutex_mii(struct usbnet *un) +{ + struct usbnet_private * const unp = un->un_pri; + + return &unp->unp_miilock; } int usbnet_mii_readreg(device_t dev, int phy, int reg, uint16_t *val) { struct usbnet * const un = device_private(dev); + struct usbnet_private * const unp = un->un_pri; usbd_status err; - mutex_enter(&un->un_lock); - if (un->un_dying || un->un_phyno != phy) { - mutex_exit(&un->un_lock); + mutex_enter(&unp->unp_lock); + if (unp->unp_dying || un->un_phyno != phy) { + mutex_exit(&unp->unp_lock); return EIO; } - mutex_exit(&un->un_lock); + mutex_exit(&unp->unp_lock); usbnet_lock_mii(un); err = uno_read_reg(un, phy, reg, val); @@ -795,14 +875,15 @@ int usbnet_mii_writereg(device_t dev, int phy, int reg, uint16_t val) { struct usbnet * const un = device_private(dev); + struct usbnet_private * const unp = un->un_pri; usbd_status err; - mutex_enter(&un->un_lock); - if (un->un_dying || un->un_phyno != phy) { - mutex_exit(&un->un_lock); + mutex_enter(&unp->unp_lock); + if (unp->unp_dying || un->un_phyno != phy) { + mutex_exit(&unp->unp_lock); return EIO; } - mutex_exit(&un->un_lock); + mutex_exit(&unp->unp_lock); usbnet_lock_mii(un); err = uno_write_reg(un, phy, reg, val); @@ -830,12 +911,13 @@ usbnet_media_upd(struct ifnet *ifp) { USBNETHIST_FUNC(); USBNETHIST_CALLED(); struct usbnet * const un = ifp->if_softc; + struct usbnet_private * const unp = un->un_pri; struct mii_data * const mii = usbnet_mii(un); - if (un->un_dying) + if (unp->unp_dying) return EIO; - un->un_link = false; + unp->unp_link = false; if (mii->mii_instance) { struct mii_softc *miisc; @@ -855,20 +937,21 @@ usbnet_ifflags_cb(struct ethercom *ec) USBNETHIST_FUNC(); USBNETHIST_CALLED(); struct ifnet *ifp = &ec->ec_if; struct usbnet *un = ifp->if_softc; + struct usbnet_private * const unp = un->un_pri; int rv = 0; - mutex_enter(&un->un_lock); + mutex_enter(&unp->unp_lock); - const int changed = ifp->if_flags ^ un->un_if_flags; + const int changed = ifp->if_flags ^ unp->unp_if_flags; if ((changed & ~(IFF_CANTCHANGE | IFF_DEBUG)) == 0) { - un->un_if_flags = ifp->if_flags; + unp->unp_if_flags = ifp->if_flags; if ((changed & IFF_PROMISC) != 0) rv = ENETRESET; } else { rv = ENETRESET; } - mutex_exit(&un->un_lock); + mutex_exit(&unp->unp_lock); return rv; } @@ -906,15 +989,17 @@ usbnet_ioctl(struct ifnet *ifp, u_long c void usbnet_stop(struct usbnet *un, struct ifnet *ifp, int disable) { + struct usbnet_private * const unp = un->un_pri; + USBNETHIST_FUNC(); USBNETHIST_CALLED(); - KASSERT(mutex_owned(&un->un_lock)); + KASSERT(mutex_owned(&unp->unp_lock)); - mutex_enter(&un->un_rxlock); - mutex_enter(&un->un_txlock); - un->un_stopping = true; - mutex_exit(&un->un_txlock); - mutex_exit(&un->un_rxlock); + mutex_enter(&unp->unp_rxlock); + mutex_enter(&unp->unp_txlock); + unp->unp_stopping = true; + mutex_exit(&unp->unp_txlock); + mutex_exit(&unp->unp_rxlock); uno_stop(un, ifp, disable); @@ -926,10 +1011,10 @@ usbnet_stop(struct usbnet *un, struct if * and unlock is already held. */ ifp->if_flags &= ~IFF_RUNNING; - un->un_timer = 0; + unp->unp_timer = 0; - callout_stop(&un->un_stat_ch); - un->un_link = false; + callout_stop(&unp->unp_stat_ch); + unp->unp_link = false; /* Stop transfers. */ usbnet_ep_stop_pipes(un); @@ -946,10 +1031,11 @@ static void usbnet_stop_ifp(struct ifnet *ifp, int disable) { struct usbnet * const un = ifp->if_softc; + struct usbnet_private * const unp = un->un_pri; - mutex_enter(&un->un_lock); + mutex_enter(&unp->unp_lock); usbnet_stop(un, ifp, disable); - mutex_exit(&un->un_lock); + mutex_exit(&unp->unp_lock); } /* @@ -962,20 +1048,21 @@ static void usbnet_tick(void *arg) { struct usbnet * const un = arg; + struct usbnet_private * const unp = un->un_pri; - mutex_enter(&un->un_lock); - if (!un->un_stopping && !un->un_dying) { + mutex_enter(&unp->unp_lock); + if (!unp->unp_stopping && !unp->unp_dying) { /* Perform periodic stuff in process context */ - usb_add_task(un->un_udev, &un->un_ticktask, USB_TASKQ_DRIVER); + usb_add_task(un->un_udev, &unp->unp_ticktask, USB_TASKQ_DRIVER); } - mutex_exit(&un->un_lock); + mutex_exit(&unp->unp_lock); } static void usbnet_watchdog(struct ifnet *ifp) { struct usbnet * const un = ifp->if_softc; - struct usbnet_cdata *cd = &un->un_cdata; + struct usbnet_cdata * const cd = un_cdata(un); usbd_status stat; ifp->if_oerrors++; @@ -985,7 +1072,7 @@ usbnet_watchdog(struct ifnet *ifp) /* * XXX index 0 */ - struct usbnet_chain *c = &un->un_cdata.uncd_tx_chain[0]; + struct usbnet_chain *c = &un_cdata(un)->uncd_tx_chain[0]; usbd_get_xfer_status(c->unc_xfer, NULL, NULL, NULL, &stat); usbnet_txeof(c->unc_xfer, c, stat); } @@ -999,35 +1086,36 @@ usbnet_tick_task(void *arg) { USBNETHIST_FUNC(); USBNETHIST_CALLED(); struct usbnet * const un = arg; + struct usbnet_private * const unp = un->un_pri; - mutex_enter(&un->un_lock); - if (un->un_stopping || un->un_dying) { - mutex_exit(&un->un_lock); + mutex_enter(&unp->unp_lock); + if (unp->unp_stopping || unp->unp_dying) { + mutex_exit(&unp->unp_lock); return; } struct ifnet * const ifp = usbnet_ifp(un); struct mii_data * const mii = usbnet_mii(un); - un->un_refcnt++; - mutex_exit(&un->un_lock); + unp->unp_refcnt++; + mutex_exit(&unp->unp_lock); - if (ifp && un->un_timer != 0 && --un->un_timer == 0) + if (ifp && unp->unp_timer != 0 && --unp->unp_timer == 0) usbnet_watchdog(ifp); if (mii && ifp) { mii_tick(mii); - if (!un->un_link) + if (!unp->unp_link) (*mii->mii_statchg)(ifp); } - mutex_enter(&un->un_lock); - if (--un->un_refcnt < 0) - cv_broadcast(&un->un_detachcv); - if (!un->un_stopping && !un->un_dying) - callout_schedule(&un->un_stat_ch, hz); - mutex_exit(&un->un_lock); + mutex_enter(&unp->unp_lock); + if (--unp->unp_refcnt < 0) + cv_broadcast(&unp->unp_detachcv); + if (!unp->unp_stopping && !unp->unp_dying) + callout_schedule(&unp->unp_stat_ch, hz); + mutex_exit(&unp->unp_lock); } static int @@ -1039,6 +1127,114 @@ usbnet_init(struct ifnet *ifp) return uno_init(un, ifp); } +/* Various accessors. */ + +void +usbnet_set_link(struct usbnet *un, bool link) +{ + un->un_pri->unp_link = link; +} + +struct ifnet * +usbnet_ifp(struct usbnet *un) +{ + return &un->un_pri->unp_ec.ec_if; +} + +struct ethercom * +usbnet_ec(struct usbnet *un) +{ + return &un->un_pri->unp_ec; +} + +struct mii_data * +usbnet_mii(struct usbnet *un) +{ + return un->un_pri->unp_ec.ec_mii; +} + +krndsource_t * +usbnet_rndsrc(struct usbnet *un) +{ + return &un->un_pri->unp_rndsrc; +} + +void * +usbnet_softc(struct usbnet *un) +{ + //return un->un_pri->unp_sc; + return un->un_sc; +} + +bool +usbnet_havelink(struct usbnet *un) +{ + return un->un_pri->unp_link; +} + +bool +usbnet_isdying(struct usbnet *un) +{ + return un->un_pri->unp_dying; +} + + +/* Locking. */ + +void +usbnet_lock(struct usbnet *un) +{ + mutex_enter(&un->un_pri->unp_lock); +} + +void +usbnet_unlock(struct usbnet *un) +{ + mutex_exit(&un->un_pri->unp_lock); +} + +kmutex_t * +usbnet_mutex(struct usbnet *un) +{ + return &un->un_pri->unp_lock; +} + +void +usbnet_lock_rx(struct usbnet *un) +{ + mutex_enter(&un->un_pri->unp_rxlock); +} + +void +usbnet_unlock_rx(struct usbnet *un) +{ + mutex_exit(&un->un_pri->unp_rxlock); +} + +kmutex_t * +usbnet_mutex_rx(struct usbnet *un) +{ + return &un->un_pri->unp_rxlock; +} + +void +usbnet_lock_tx(struct usbnet *un) +{ + mutex_enter(&un->un_pri->unp_txlock); +} + +void +usbnet_unlock_tx(struct usbnet *un) +{ + mutex_exit(&un->un_pri->unp_txlock); +} + +kmutex_t * +usbnet_mutex_tx(struct usbnet *un) +{ + return &un->un_pri->unp_txlock; +} + /* Autoconf management. */ static bool @@ -1061,62 +1257,51 @@ usbnet_empty_eaddr(struct usbnet *un) * To skip ethernet configuration (eg, point-to-point), make sure that * the un_eaddr[] is fully zero. */ + void usbnet_attach(struct usbnet *un, - const char *detname, /* detach cv name */ - unsigned rx_list_cnt, /* size of rx chain list */ - unsigned tx_list_cnt, /* size of tx chain list */ - unsigned rx_flags, /* flags for rx xfer */ - unsigned tx_flags, /* flags for tx xfer */ - unsigned rx_bufsz, /* size of rx buffers */ - unsigned tx_bufsz) /* size of tx buffers */ + const char *detname) /* detach cv name */ { USBNETHIST_FUNC(); USBNETHIST_CALLED(); - struct usbnet_cdata *cd = &un->un_cdata; /* Required inputs. */ KASSERT(un->un_ops->uno_tx_prepare); KASSERT(un->un_ops->uno_rx_loop); KASSERT(un->un_ops->uno_init); - KASSERT(rx_bufsz); - KASSERT(tx_bufsz); - KASSERT(rx_list_cnt); - KASSERT(tx_list_cnt); - - cd->uncd_rx_xfer_flags = rx_flags; - cd->uncd_tx_xfer_flags = tx_flags; - cd->uncd_rx_list_cnt = rx_list_cnt; - cd->uncd_tx_list_cnt = tx_list_cnt; - cd->uncd_rx_bufsz = rx_bufsz; - cd->uncd_tx_bufsz = tx_bufsz; - - ether_set_ifflags_cb(&un->un_ec, usbnet_ifflags_cb); - - usb_init_task(&un->un_ticktask, usbnet_tick_task, un, USB_TASKQ_MPSAFE); - callout_init(&un->un_stat_ch, CALLOUT_MPSAFE); - callout_setfunc(&un->un_stat_ch, usbnet_tick, un); - - mutex_init(&un->un_miilock, MUTEX_DEFAULT, IPL_NONE); - mutex_init(&un->un_txlock, MUTEX_DEFAULT, IPL_SOFTUSB); - mutex_init(&un->un_rxlock, MUTEX_DEFAULT, IPL_SOFTUSB); - mutex_init(&un->un_lock, MUTEX_DEFAULT, IPL_NONE); - cv_init(&un->un_detachcv, detname); + KASSERT(un->un_rx_bufsz); + KASSERT(un->un_tx_bufsz); + KASSERT(un->un_rx_list_cnt); + KASSERT(un->un_tx_list_cnt); + + un->un_pri = kmem_zalloc(sizeof(*un->un_pri), KM_SLEEP); + struct usbnet_private * const unp = un->un_pri; + + usb_init_task(&unp->unp_ticktask, usbnet_tick_task, un, USB_TASKQ_MPSAFE); + callout_init(&unp->unp_stat_ch, CALLOUT_MPSAFE); + callout_setfunc(&unp->unp_stat_ch, usbnet_tick, un); + + mutex_init(&unp->unp_miilock, MUTEX_DEFAULT, IPL_NONE); + mutex_init(&unp->unp_txlock, MUTEX_DEFAULT, IPL_SOFTUSB); + mutex_init(&unp->unp_rxlock, MUTEX_DEFAULT, IPL_SOFTUSB); + mutex_init(&unp->unp_lock, MUTEX_DEFAULT, IPL_NONE); + cv_init(&unp->unp_detachcv, detname); - rnd_attach_source(&un->un_rndsrc, device_xname(un->un_dev), + rnd_attach_source(&unp->unp_rndsrc, device_xname(un->un_dev), RND_TYPE_NET, RND_FLAG_DEFAULT); usbnet_rx_list_alloc(un); usbnet_tx_list_alloc(un); - un->un_attached = true; + unp->unp_attached = true; } static void usbnet_attach_mii(struct usbnet *un, int mii_flags) { USBNETHIST_FUNC(); USBNETHIST_CALLED(); - struct mii_data * const mii = &un->un_mii; - struct ifnet *ifp = usbnet_ifp(un); + struct usbnet_private * const unp = un->un_pri; + struct mii_data * const mii = &unp->unp_mii; + struct ifnet * const ifp = usbnet_ifp(un); KASSERT(un->un_ops->uno_read_reg); KASSERT(un->un_ops->uno_write_reg); @@ -1128,7 +1313,7 @@ usbnet_attach_mii(struct usbnet *un, int mii->mii_statchg = usbnet_mii_statchg; mii->mii_flags = MIIF_AUTOTSLEEP; - un->un_ec.ec_mii = mii; + usbnet_ec(un)->ec_mii = mii; ifmedia_init(&mii->mii_media, 0, usbnet_media_upd, ether_mediastatus); mii_attach(un->un_dev, mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY, mii_flags); @@ -1148,9 +1333,10 @@ usbnet_attach_ifp(struct usbnet *un, int mii_flags) /* additional mii_attach flags */ { USBNETHIST_FUNC(); USBNETHIST_CALLED(); - struct ifnet *ifp = usbnet_ifp(un); + struct usbnet_private * const unp = un->un_pri; + struct ifnet * const ifp = usbnet_ifp(un); - KASSERT(un->un_attached); + KASSERT(unp->unp_attached); IFQ_SET_READY(&ifp->if_snd); @@ -1168,7 +1354,7 @@ usbnet_attach_ifp(struct usbnet *un, if (have_mii) usbnet_attach_mii(un, mii_flags); else - un->un_link = true; + unp->unp_link = true; /* Attach the interface. */ if_attach(ifp); @@ -1178,6 +1364,7 @@ usbnet_attach_ifp(struct usbnet *un, * instead attach bpf here.. */ if (!usbnet_empty_eaddr(un)) { + ether_set_ifflags_cb(&unp->unp_ec, usbnet_ifflags_cb); aprint_normal_dev(un->un_dev, "Ethernet address %s\n", ether_sprintf(un->un_eaddr)); ether_ifattach(ifp, un->un_eaddr); @@ -1197,19 +1384,20 @@ usbnet_detach(device_t self, int flags) { USBNETHIST_FUNC(); USBNETHIST_CALLED(); struct usbnet * const un = device_private(self); - struct ifnet *ifp = usbnet_ifp(un); - struct mii_data *mii = usbnet_mii(un); + struct ifnet * const ifp = usbnet_ifp(un); + struct mii_data * const mii = usbnet_mii(un); + struct usbnet_private * const unp = un->un_pri; - mutex_enter(&un->un_lock); - un->un_dying = true; - mutex_exit(&un->un_lock); + mutex_enter(&unp->unp_lock); + unp->unp_dying = true; + mutex_exit(&unp->unp_lock); /* Detached before attached finished, so just bail out. */ - if (!un->un_attached) + if (!unp->unp_attached) return 0; - callout_halt(&un->un_stat_ch, NULL); - usb_rem_task_wait(un->un_udev, &un->un_ticktask, USB_TASKQ_DRIVER, NULL); + callout_halt(&unp->unp_stat_ch, NULL); + usb_rem_task_wait(un->un_udev, &unp->unp_ticktask, USB_TASKQ_DRIVER, NULL); if (ifp->if_flags & IFF_RUNNING) { IFNET_LOCK(ifp); @@ -1217,19 +1405,19 @@ usbnet_detach(device_t self, int flags) IFNET_UNLOCK(ifp); } - mutex_enter(&un->un_lock); - un->un_refcnt--; - while (un->un_refcnt > 0) { + mutex_enter(&unp->unp_lock); + unp->unp_refcnt--; + while (unp->unp_refcnt > 0) { /* Wait for processes to go away */ - cv_wait(&un->un_detachcv, &un->un_lock); + cv_wait(&unp->unp_detachcv, &unp->unp_lock); } - mutex_exit(&un->un_lock); + mutex_exit(&unp->unp_lock); usbnet_rx_list_free(un); usbnet_tx_list_free(un); - callout_destroy(&un->un_stat_ch); - rnd_detach_source(&un->un_rndsrc); + callout_destroy(&unp->unp_stat_ch); + rnd_detach_source(&unp->unp_rndsrc); if (mii) { mii_detach(mii, MII_PHY_ANY, MII_OFFSET_ANY); @@ -1243,16 +1431,18 @@ usbnet_detach(device_t self, int flags) if_detach(ifp); } - cv_destroy(&un->un_detachcv); - mutex_destroy(&un->un_lock); - mutex_destroy(&un->un_rxlock); - mutex_destroy(&un->un_txlock); - mutex_destroy(&un->un_miilock); + cv_destroy(&unp->unp_detachcv); + mutex_destroy(&unp->unp_lock); + mutex_destroy(&unp->unp_rxlock); + mutex_destroy(&unp->unp_txlock); + mutex_destroy(&unp->unp_miilock); pmf_device_deregister(un->un_dev); usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, un->un_udev, un->un_dev); + kmem_free(unp, sizeof(*unp)); + return 0; } @@ -1261,21 +1451,22 @@ usbnet_activate(device_t self, devact_t { USBNETHIST_FUNC(); USBNETHIST_CALLED(); struct usbnet * const un = device_private(self); + struct usbnet_private * const unp = un->un_pri; struct ifnet * const ifp = usbnet_ifp(un); switch (act) { case DVACT_DEACTIVATE: if_deactivate(ifp); - mutex_enter(&un->un_lock); - un->un_dying = true; - mutex_exit(&un->un_lock); - - mutex_enter(&un->un_rxlock); - mutex_enter(&un->un_txlock); - un->un_stopping = true; - mutex_exit(&un->un_txlock); - mutex_exit(&un->un_rxlock); + mutex_enter(&unp->unp_lock); + unp->unp_dying = true; + mutex_exit(&unp->unp_lock); + + mutex_enter(&unp->unp_rxlock); + mutex_enter(&unp->unp_txlock); + unp->unp_stopping = true; + mutex_exit(&unp->unp_txlock); + mutex_exit(&unp->unp_rxlock); return 0; default: Index: src/sys/dev/usb/usbnet.h diff -u src/sys/dev/usb/usbnet.h:1.8 src/sys/dev/usb/usbnet.h:1.9 --- src/sys/dev/usb/usbnet.h:1.8 Fri Aug 9 02:14:35 2019 +++ src/sys/dev/usb/usbnet.h Sat Aug 10 02:17:36 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: usbnet.h,v 1.8 2019/08/09 02:14:35 mrg Exp $ */ +/* $NetBSD: usbnet.h,v 1.9 2019/08/10 02:17:36 mrg Exp $ */ /* * Copyright (c) 2019 Matthew R. Green @@ -113,23 +113,6 @@ struct usbnet_chain { uint8_t *unc_buf; }; -struct usbnet_cdata { - struct usbnet_chain *uncd_tx_chain; - struct usbnet_chain *uncd_rx_chain; - - unsigned uncd_rx_bufsz; - unsigned uncd_tx_bufsz; - unsigned uncd_rx_list_cnt; - unsigned uncd_tx_list_cnt; - - int uncd_rx_xfer_flags; - int uncd_tx_xfer_flags; - - int uncd_tx_prod; - int uncd_tx_cnt; - int uncd_rx_cnt; -}; - /* * Extend this as necessary. axe(4) claims to want 6 total, but * does not implement them. @@ -180,162 +163,144 @@ struct usbnet_ops { }; /* - * Generic USB ethernet structure. Use this as ifp->if_softc and - * set as device_private() in attach. + * USB interrupt pipe support. Use this if usbd_open_pipe_intr() should + * be used for the interrupt pipe. + */ +struct usbnet_intr { + /* + * Point un_intr to this structure to use usbd_open_pipe_intr() not + * usbd_open_pipe() for USBNET_ENDPT_INTR, with this buffer, size, + * and interval. + */ + void *uni_buf; + unsigned uni_bufsz; + unsigned uni_interval; +}; + +/* + * Generic USB ethernet structure. Use this as ifp->if_softc and set as + * device_private() in attach unless already using struct usbnet here. * * Devices without MII should call usbnet_attach_ifp() with have_mii set * to true, and should ensure that the un_statchg_cb callback sets the * un_link member. Devices without MII have this forced to true. */ +struct usbnet_private; struct usbnet { + /* + * This section should be filled in before calling + * usbnet_attach(). + */ void *un_sc; /* real softc */ device_t un_dev; struct usbd_interface *un_iface; - struct usbd_device * un_udev; - - krndsource_t un_rndsrc; + struct usbd_device *un_udev; struct usbnet_ops *un_ops; + struct usbnet_intr *un_intr; - struct ethercom un_ec; - struct mii_data un_mii; - int un_phyno; - uint8_t un_eaddr[ETHER_ADDR_LEN]; + /* Inputs for rx/tx chain control. */ + unsigned un_rx_bufsz; + unsigned un_tx_bufsz; + unsigned un_rx_list_cnt; + unsigned un_tx_list_cnt; + int un_rx_xfer_flags; + int un_tx_xfer_flags; + /* + * This section should be filled in before calling + * usbnet_attach_ifp(). + */ enum usbnet_ep un_ed[USBNET_ENDPT_MAX]; - struct usbd_pipe *un_ep[USBNET_ENDPT_MAX]; - struct usbnet_cdata un_cdata; - struct callout un_stat_ch; - int un_if_flags; - - /* This is for driver to use. */ - unsigned un_flags; + /* MII specific. Not used without MII. */ + int un_phyno; + /* Ethernet specific. All zeroes indicates non-Ethernet. */ + uint8_t un_eaddr[ETHER_ADDR_LEN]; /* - * - un_lock protects most of the structure - * - un_miilock must be held to access this device's MII bus - * - un_rxlock protects the rx path and its data - * - un_txlock protects the tx path and its data - * - un_detachcv handles detach vs open references + * This section is for driver to use, not touched by usbnet. */ - kmutex_t un_lock; - kmutex_t un_miilock; - kmutex_t un_rxlock; - kmutex_t un_txlock; - kcondvar_t un_detachcv; - - struct usb_task un_ticktask; - - int un_refcnt; - int un_timer; - - bool un_dying; - bool un_stopping; - bool un_link; - bool un_attached; - - struct timeval un_rx_notice; - struct timeval un_tx_notice; - struct timeval un_intr_notice; + unsigned un_flags; /* - * if un_intr_buf is not NULL, use usbd_open_pipe_intr() not - * usbd_open_pipe() for USBNET_ENDPT_INTR, with this buffer, - * size, and interval. + * This section is private to usbnet. Don't touch. */ - void *un_intr_buf; - unsigned un_intr_bufsz; - unsigned un_intr_interval; + struct usbnet_private *un_pri; }; -#define usbnet_ifp(un) (&(un)->un_ec.ec_if) -#define usbnet_ec(un) (&(un)->un_ec) -#define usbnet_rndsrc(un) (&(un)->un_rndsrc) -#define usbnet_mii(un) ((un)->un_ec.ec_mii) -#define usbnet_softc(un) ((un)->un_sc) -#define usbnet_isdying(un) ((un)->un_dying) +/* Various accessors. */ -/* - * Endpoint / rx/tx chain management: - * - * usbnet_attach() allocates rx and tx chains - * usbnet_init_rx_tx() open pipes, initialises the rx/tx chains for use - * usbnet_stop() stops pipes, cleans (not frees) rx/tx chains, locked - * version assumes un_lock is held - * usbnet_detach() frees the rx/tx chains - * - * Setup un_ed[] with valid end points before calling usbnet_init_rx_tx(). - * Will return with un_ep[] initialised upon success. - */ -int usbnet_init_rx_tx(struct usbnet * const); - -/* locking */ -static __inline__ void -usbnet_lock(struct usbnet *un) -{ - mutex_enter(&un->un_lock); -} +void usbnet_set_link(struct usbnet *, bool); -static __inline__ void -usbnet_unlock(struct usbnet *un) -{ - mutex_exit(&un->un_lock); -} +struct ifnet *usbnet_ifp(struct usbnet *); +struct ethercom *usbnet_ec(struct usbnet *); +struct mii_data *usbnet_mii(struct usbnet *); +krndsource_t *usbnet_rndsrc(struct usbnet *); +void *usbnet_softc(struct usbnet *); -static __inline__ void -usbnet_isowned(struct usbnet *un) -{ - KASSERT(mutex_owned(&un->un_lock)); -} +bool usbnet_havelink(struct usbnet *); +bool usbnet_isdying(struct usbnet *); -static __inline__ void -usbnet_lock_rx(struct usbnet *un) -{ - mutex_enter(&un->un_rxlock); -} +/* + * Locking. Note that the isowned() are implemented here so that + * empty-KASSERT() causes them to be elided for non-DIAG builds. + */ +void usbnet_lock(struct usbnet *); +void usbnet_unlock(struct usbnet *); +kmutex_t *usbnet_mutex(struct usbnet *); static __inline__ void -usbnet_unlock_rx(struct usbnet *un) +usbnet_isowned(struct usbnet *un) { - mutex_exit(&un->un_rxlock); + KASSERT(mutex_owned(usbnet_mutex(un))); } +void usbnet_lock_rx(struct usbnet *); +void usbnet_unlock_rx(struct usbnet *); +kmutex_t *usbnet_mutex_rx(struct usbnet *); static __inline__ void usbnet_isowned_rx(struct usbnet *un) { - KASSERT(mutex_owned(&un->un_rxlock)); -} - -static __inline__ void -usbnet_lock_tx(struct usbnet *un) -{ - mutex_enter(&un->un_txlock); -} - -static __inline__ void -usbnet_unlock_tx(struct usbnet *un) -{ - mutex_exit(&un->un_txlock); + KASSERT(mutex_owned(usbnet_mutex_rx(un))); } +void usbnet_lock_tx(struct usbnet *); +void usbnet_unlock_tx(struct usbnet *); +kmutex_t *usbnet_mutex_tx(struct usbnet *); static __inline__ void usbnet_isowned_tx(struct usbnet *un) { - KASSERT(mutex_owned(&un->un_txlock)); + KASSERT(mutex_owned(usbnet_mutex_tx(un))); } -/* mii */ +/* + * Endpoint / rx/tx chain management: + * + * usbnet_attach() allocates rx and tx chains + * usbnet_init_rx_tx() open pipes, initialises the rx/tx chains for use + * usbnet_stop() stops pipes, cleans (not frees) rx/tx chains, locked + * version assumes un_lock is held + * usbnet_detach() frees the rx/tx chains + * + * Setup un_ed[] with valid end points before calling usbnet_attach(). + * Call usbnet_init_rx_tx() to initialise pipes, which will be open + * upon success. + */ +int usbnet_init_rx_tx(struct usbnet * const); + +/* MII. */ void usbnet_lock_mii(struct usbnet *); void usbnet_lock_mii_un_locked(struct usbnet *); void usbnet_unlock_mii(struct usbnet *); void usbnet_unlock_mii_un_locked(struct usbnet *); - +kmutex_t *usbnet_mutex_mii(struct usbnet *); static __inline__ void usbnet_isowned_mii(struct usbnet *un) { - KASSERT(mutex_owned(&un->un_miilock)); + KASSERT(mutex_owned(usbnet_mutex_mii(un))); } + int usbnet_mii_readreg(device_t, int, int, uint16_t *); int usbnet_mii_writereg(device_t, int, int, uint16_t); void usbnet_mii_statchg(struct ifnet *); @@ -346,8 +311,7 @@ void usbnet_enqueue(struct usbnet * cons void usbnet_input(struct usbnet * const, uint8_t *, size_t); /* autoconf */ -void usbnet_attach(struct usbnet *un, const char *, unsigned, unsigned, - unsigned, unsigned, unsigned, unsigned); +void usbnet_attach(struct usbnet *un, const char *); void usbnet_attach_ifp(struct usbnet *, bool, unsigned, unsigned, int); int usbnet_detach(device_t, int); int usbnet_activate(device_t, devact_t); Index: src/sys/sys/param.h diff -u src/sys/sys/param.h:1.604 src/sys/sys/param.h:1.605 --- src/sys/sys/param.h:1.604 Fri Aug 9 01:17:33 2019 +++ src/sys/sys/param.h Sat Aug 10 02:17:36 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: param.h,v 1.604 2019/08/09 01:17:33 mrg Exp $ */ +/* $NetBSD: param.h,v 1.605 2019/08/10 02:17:36 mrg Exp $ */ /*- * Copyright (c) 1982, 1986, 1989, 1993 @@ -67,7 +67,7 @@ * 2.99.9 (299000900) */ -#define __NetBSD_Version__ 999000500 /* NetBSD 9.99.5 */ +#define __NetBSD_Version__ 999000600 /* NetBSD 9.99.6 */ #define __NetBSD_Prereq__(M,m,p) (((((M) * 100000000) + \ (m) * 1000000) + (p) * 100) <= __NetBSD_Version__)