summaryrefslogtreecommitdiffstats
path: root/freebsd/sys/dev
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2018-08-21 13:47:02 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2018-09-21 10:29:41 +0200
commitbcdce02d9bc8150e1d191ed5ca9da45b7604964a (patch)
tree3b2faf509db7672ee1fc98857736470be97e7ed8 /freebsd/sys/dev
parentUpdate to FreeBSD head 2018-04-01 (diff)
downloadrtems-libbsd-bcdce02d9bc8150e1d191ed5ca9da45b7604964a.tar.bz2
Update to FreeBSD head 2018-06-01
Git mirror commit fb63610a69b0eb7f69a201ba05c4c1a7a2739cf9. Update #3472.
Diffstat (limited to 'freebsd/sys/dev')
-rw-r--r--freebsd/sys/dev/bce/if_bce.c5
-rw-r--r--freebsd/sys/dev/bfe/if_bfe.c2
-rw-r--r--freebsd/sys/dev/bge/if_bge.c111
-rw-r--r--freebsd/sys/dev/dc/if_dc.c10
-rw-r--r--freebsd/sys/dev/dwc/if_dwc.c2
-rw-r--r--freebsd/sys/dev/e1000/e1000_80003es2lan.c87
-rw-r--r--freebsd/sys/dev/e1000/e1000_82571.c157
-rw-r--r--freebsd/sys/dev/e1000/e1000_82575.c92
-rw-r--r--freebsd/sys/dev/e1000/e1000_hw.h3
-rw-r--r--freebsd/sys/dev/e1000/e1000_i210.c150
-rw-r--r--freebsd/sys/dev/e1000/e1000_i210.h2
-rw-r--r--freebsd/sys/dev/e1000/e1000_ich8lan.c20
-rw-r--r--freebsd/sys/dev/e1000/e1000_mac.c248
-rw-r--r--freebsd/sys/dev/e1000/e1000_mac.h7
-rw-r--r--freebsd/sys/dev/e1000/e1000_osdep.h78
-rw-r--r--freebsd/sys/dev/e1000/em_txrx.c34
-rw-r--r--freebsd/sys/dev/e1000/if_em.c17
-rw-r--r--freebsd/sys/dev/e1000/igb_txrx.c16
-rw-r--r--freebsd/sys/dev/evdev/uinput.c9
-rw-r--r--freebsd/sys/dev/evdev/uinput.h7
-rw-r--r--freebsd/sys/dev/fdt/fdt_common.c206
-rw-r--r--freebsd/sys/dev/fdt/fdt_common.h9
-rw-r--r--freebsd/sys/dev/ffec/if_ffec.c2
-rw-r--r--freebsd/sys/dev/gpio/ofw_gpiobus.c2
-rw-r--r--freebsd/sys/dev/mmc/mmcreg.h160
-rw-r--r--freebsd/sys/dev/mmc/mmcsd.c145
-rw-r--r--freebsd/sys/dev/nvme/nvme.h17
-rw-r--r--freebsd/sys/dev/ofw/ofw_bus_subr.c61
-rw-r--r--freebsd/sys/dev/ofw/ofw_bus_subr.h2
-rw-r--r--freebsd/sys/dev/ofw/ofw_fdt.c2
-rw-r--r--freebsd/sys/dev/ofw/openfirm.c63
-rw-r--r--freebsd/sys/dev/ofw/openfirm.h6
-rw-r--r--freebsd/sys/dev/pci/pci_pci.c18
-rw-r--r--freebsd/sys/dev/pci/pci_user.c434
-rw-r--r--freebsd/sys/dev/re/if_re.c76
-rw-r--r--freebsd/sys/dev/rtwn/if_rtwn_rx.c2
-rw-r--r--freebsd/sys/dev/tsec/if_tsec.c2
-rw-r--r--freebsd/sys/dev/usb/input/ukbd.c1
-rw-r--r--freebsd/sys/dev/usb/input/usb_rdesc.h28
-rw-r--r--freebsd/sys/dev/usb/net/if_aue.c2
-rw-r--r--freebsd/sys/dev/usb/net/if_axe.c2
-rw-r--r--freebsd/sys/dev/usb/net/if_axge.c2
-rw-r--r--freebsd/sys/dev/usb/net/if_cue.c2
-rw-r--r--freebsd/sys/dev/usb/net/if_kue.c2
-rw-r--r--freebsd/sys/dev/usb/net/if_mos.c2
-rw-r--r--freebsd/sys/dev/usb/net/if_rue.c2
-rw-r--r--freebsd/sys/dev/usb/net/if_smsc.c10
-rw-r--r--freebsd/sys/dev/usb/net/if_udav.c2
-rw-r--r--freebsd/sys/dev/usb/net/if_ure.c2
-rw-r--r--freebsd/sys/dev/usb/net/usb_ethernet.c11
-rw-r--r--freebsd/sys/dev/usb/net/usb_ethernet.h1
-rw-r--r--freebsd/sys/dev/usb/serial/uchcom.c68
-rw-r--r--freebsd/sys/dev/usb/serial/umodem.c2
-rw-r--r--freebsd/sys/dev/usb/serial/usb_serial.c78
-rw-r--r--freebsd/sys/dev/usb/serial/usb_serial.h5
-rw-r--r--freebsd/sys/dev/usb/serial/uslcom.c126
-rw-r--r--freebsd/sys/dev/usb/usb_device.c2
-rw-r--r--freebsd/sys/dev/usb/usb_ioctl.h1
-rw-r--r--freebsd/sys/dev/usb/usb_request.c6
-rw-r--r--freebsd/sys/dev/usb/wlan/if_rsu.c2
-rw-r--r--freebsd/sys/dev/usb/wlan/if_zyd.c2
61 files changed, 1399 insertions, 1226 deletions
diff --git a/freebsd/sys/dev/bce/if_bce.c b/freebsd/sys/dev/bce/if_bce.c
index a2e4c804..61c9708d 100644
--- a/freebsd/sys/dev/bce/if_bce.c
+++ b/freebsd/sys/dev/bce/if_bce.c
@@ -531,7 +531,8 @@ MODULE_DEPEND(bce, miibus, 1, 1, 1);
DRIVER_MODULE(bce, pci, bce_driver, bce_devclass, NULL, NULL);
DRIVER_MODULE(miibus, bce, miibus_driver, miibus_devclass, NULL, NULL);
-
+MODULE_PNP_INFO("U16:vendor;U16:device;U16:#;U16:#;D:#", pci, bce,
+ bce_devs, sizeof(bce_devs[0]), nitems(bce_devs) - 1);
/****************************************************************************/
/* Tunable device values */
@@ -8118,7 +8119,7 @@ bce_set_rx_mode(struct bce_softc *sc)
DBPRINT(sc, BCE_INFO_MISC, "Enabling selective multicast mode.\n");
if_maddr_rlock(ifp);
- TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
+ CK_STAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
if (ifma->ifma_addr->sa_family != AF_LINK)
continue;
h = ether_crc32_le(LLADDR((struct sockaddr_dl *)
diff --git a/freebsd/sys/dev/bfe/if_bfe.c b/freebsd/sys/dev/bfe/if_bfe.c
index 63825a99..c07d87fb 100644
--- a/freebsd/sys/dev/bfe/if_bfe.c
+++ b/freebsd/sys/dev/bfe/if_bfe.c
@@ -1111,7 +1111,7 @@ bfe_set_rx_mode(struct bfe_softc *sc)
else {
val &= ~BFE_RXCONF_ALLMULTI;
if_maddr_rlock(ifp);
- TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
+ CK_STAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
if (ifma->ifma_addr->sa_family != AF_LINK)
continue;
bfe_cam_write(sc,
diff --git a/freebsd/sys/dev/bge/if_bge.c b/freebsd/sys/dev/bge/if_bge.c
index 956ee52f..aba0b05d 100644
--- a/freebsd/sys/dev/bge/if_bge.c
+++ b/freebsd/sys/dev/bge/if_bge.c
@@ -102,6 +102,7 @@ __FBSDID("$FreeBSD$");
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
+#include <netinet/netdump/netdump.h>
#include <machine/bus.h>
#include <machine/resource.h>
@@ -428,8 +429,9 @@ static int bge_encap(struct bge_softc *, struct mbuf **, uint32_t *);
static void bge_intr(void *);
static int bge_msi_intr(void *);
static void bge_intr_task(void *, int);
-static void bge_start_locked(if_t);
static void bge_start(if_t);
+static void bge_start_locked(if_t);
+static void bge_start_tx(struct bge_softc *, uint32_t);
static int bge_ioctl(if_t, u_long, caddr_t);
static void bge_init_locked(struct bge_softc *);
static void bge_init(void *);
@@ -519,6 +521,8 @@ static void bge_add_sysctl_stats(struct bge_softc *, struct sysctl_ctx_list *,
struct sysctl_oid_list *);
static int bge_sysctl_stats(SYSCTL_HANDLER_ARGS);
+NETDUMP_DEFINE(bge);
+
static device_method_t bge_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, bge_probe),
@@ -3943,8 +3947,12 @@ again:
if (error) {
ether_ifdetach(ifp);
device_printf(sc->bge_dev, "couldn't set up irq\n");
+ goto fail;
}
+ /* Attach driver netdump methods. */
+ NETDUMP_SET(ifp, bge);
+
fail:
if (error)
bge_detach(dev);
@@ -5391,22 +5399,26 @@ bge_start_locked(if_t ifp)
if_bpfmtap(ifp, m_head);
}
- if (count > 0) {
- bus_dmamap_sync(sc->bge_cdata.bge_tx_ring_tag,
- sc->bge_cdata.bge_tx_ring_map, BUS_DMASYNC_PREWRITE);
- /* Transmit. */
+ if (count > 0)
+ bge_start_tx(sc, prodidx);
+}
+
+static void
+bge_start_tx(struct bge_softc *sc, uint32_t prodidx)
+{
+
+ bus_dmamap_sync(sc->bge_cdata.bge_tx_ring_tag,
+ sc->bge_cdata.bge_tx_ring_map, BUS_DMASYNC_PREWRITE);
+ /* Transmit. */
+ bge_writembx(sc, BGE_MBX_TX_HOST_PROD0_LO, prodidx);
+ /* 5700 b2 errata */
+ if (sc->bge_chiprev == BGE_CHIPREV_5700_BX)
bge_writembx(sc, BGE_MBX_TX_HOST_PROD0_LO, prodidx);
- /* 5700 b2 errata */
- if (sc->bge_chiprev == BGE_CHIPREV_5700_BX)
- bge_writembx(sc, BGE_MBX_TX_HOST_PROD0_LO, prodidx);
- sc->bge_tx_prodidx = prodidx;
+ sc->bge_tx_prodidx = prodidx;
- /*
- * Set a timeout in case the chip goes out to lunch.
- */
- sc->bge_timer = BGE_TX_TIMEOUT;
- }
+ /* Set a timeout in case the chip goes out to lunch. */
+ sc->bge_timer = BGE_TX_TIMEOUT;
}
/*
@@ -6798,3 +6810,74 @@ bge_get_counter(if_t ifp, ift_counter cnt)
return (if_get_counter_default(ifp, cnt));
}
}
+
+#ifdef NETDUMP
+static void
+bge_netdump_init(if_t ifp, int *nrxr, int *ncl, int *clsize)
+{
+ struct bge_softc *sc;
+
+ sc = if_getsoftc(ifp);
+ BGE_LOCK(sc);
+ *nrxr = sc->bge_return_ring_cnt;
+ *ncl = NETDUMP_MAX_IN_FLIGHT;
+ if ((sc->bge_flags & BGE_FLAG_JUMBO_STD) != 0 &&
+ (if_getmtu(sc->bge_ifp) + ETHER_HDR_LEN + ETHER_CRC_LEN +
+ ETHER_VLAN_ENCAP_LEN > (MCLBYTES - ETHER_ALIGN)))
+ *clsize = MJUM9BYTES;
+ else
+ *clsize = MCLBYTES;
+ BGE_UNLOCK(sc);
+}
+
+static void
+bge_netdump_event(if_t ifp __unused, enum netdump_ev event __unused)
+{
+}
+
+static int
+bge_netdump_transmit(if_t ifp, struct mbuf *m)
+{
+ struct bge_softc *sc;
+ uint32_t prodidx;
+ int error;
+
+ sc = if_getsoftc(ifp);
+ if ((if_getdrvflags(ifp) & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
+ IFF_DRV_RUNNING)
+ return (1);
+
+ prodidx = sc->bge_tx_prodidx;
+ error = bge_encap(sc, &m, &prodidx);
+ if (error == 0)
+ bge_start_tx(sc, prodidx);
+ return (error);
+}
+
+static int
+bge_netdump_poll(if_t ifp, int count)
+{
+ struct bge_softc *sc;
+ uint32_t rx_prod, tx_cons;
+
+ sc = if_getsoftc(ifp);
+ if ((if_getdrvflags(ifp) & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
+ IFF_DRV_RUNNING)
+ return (1);
+
+ bus_dmamap_sync(sc->bge_cdata.bge_status_tag,
+ sc->bge_cdata.bge_status_map,
+ BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
+
+ rx_prod = sc->bge_ldata.bge_status_block->bge_idx[0].bge_rx_prod_idx;
+ tx_cons = sc->bge_ldata.bge_status_block->bge_idx[0].bge_tx_cons_idx;
+
+ bus_dmamap_sync(sc->bge_cdata.bge_status_tag,
+ sc->bge_cdata.bge_status_map,
+ BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+
+ (void)bge_rxeof(sc, rx_prod, 0);
+ bge_txeof(sc, tx_cons);
+ return (0);
+}
+#endif /* NETDUMP */
diff --git a/freebsd/sys/dev/dc/if_dc.c b/freebsd/sys/dev/dc/if_dc.c
index 3339b83d..ac34a20a 100644
--- a/freebsd/sys/dev/dc/if_dc.c
+++ b/freebsd/sys/dev/dc/if_dc.c
@@ -999,7 +999,7 @@ dc_setfilt_21143(struct dc_softc *sc)
DC_CLRBIT(sc, DC_NETCFG, DC_NETCFG_RX_ALLMULTI);
if_maddr_rlock(ifp);
- TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
+ CK_STAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
if (ifma->ifma_addr->sa_family != AF_LINK)
continue;
h = dc_mchash_le(sc,
@@ -1077,7 +1077,7 @@ dc_setfilt_admtek(struct dc_softc *sc)
/* Now program new ones. */
if_maddr_rlock(ifp);
- TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
+ CK_STAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
if (ifma->ifma_addr->sa_family != AF_LINK)
continue;
if (DC_IS_CENTAUR(sc))
@@ -1150,7 +1150,7 @@ dc_setfilt_asix(struct dc_softc *sc)
/* now program new ones */
if_maddr_rlock(ifp);
- TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
+ CK_STAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
if (ifma->ifma_addr->sa_family != AF_LINK)
continue;
h = dc_mchash_be(LLADDR((struct sockaddr_dl *)ifma->ifma_addr));
@@ -1211,7 +1211,7 @@ dc_setfilt_uli(struct dc_softc *sc)
/* Now build perfect filters. */
mcnt = 0;
if_maddr_rlock(ifp);
- TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
+ CK_STAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
if (ifma->ifma_addr->sa_family != AF_LINK)
continue;
if (mcnt >= DC_ULI_FILTER_NPERF) {
@@ -1296,7 +1296,7 @@ dc_setfilt_xircom(struct dc_softc *sc)
DC_CLRBIT(sc, DC_NETCFG, DC_NETCFG_RX_ALLMULTI);
if_maddr_rlock(ifp);
- TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
+ CK_STAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
if (ifma->ifma_addr->sa_family != AF_LINK)
continue;
h = dc_mchash_le(sc,
diff --git a/freebsd/sys/dev/dwc/if_dwc.c b/freebsd/sys/dev/dwc/if_dwc.c
index badbd807..895fdfe5 100644
--- a/freebsd/sys/dev/dwc/if_dwc.c
+++ b/freebsd/sys/dev/dwc/if_dwc.c
@@ -702,7 +702,7 @@ dwc_setup_rxfilter(struct dwc_softc *sc)
for (i = 0; i < nhash; i++)
hash[i] = 0;
if_maddr_rlock(ifp);
- TAILQ_FOREACH(ifma, &sc->ifp->if_multiaddrs, ifma_link) {
+ CK_STAILQ_FOREACH(ifma, &sc->ifp->if_multiaddrs, ifma_link) {
if (ifma->ifma_addr->sa_family != AF_LINK)
continue;
crc = ether_crc32_le(LLADDR((struct sockaddr_dl *)
diff --git a/freebsd/sys/dev/e1000/e1000_80003es2lan.c b/freebsd/sys/dev/e1000/e1000_80003es2lan.c
index 50175d2a..6b05840f 100644
--- a/freebsd/sys/dev/e1000/e1000_80003es2lan.c
+++ b/freebsd/sys/dev/e1000/e1000_80003es2lan.c
@@ -62,7 +62,6 @@ static s32 e1000_reset_hw_80003es2lan(struct e1000_hw *hw);
static s32 e1000_init_hw_80003es2lan(struct e1000_hw *hw);
static s32 e1000_setup_copper_link_80003es2lan(struct e1000_hw *hw);
static void e1000_clear_hw_cntrs_80003es2lan(struct e1000_hw *hw);
-static s32 e1000_acquire_swfw_sync_80003es2lan(struct e1000_hw *hw, u16 mask);
static s32 e1000_cfg_kmrn_10_100_80003es2lan(struct e1000_hw *hw, u16 duplex);
static s32 e1000_cfg_kmrn_1000_80003es2lan(struct e1000_hw *hw);
static s32 e1000_cfg_on_link_up_80003es2lan(struct e1000_hw *hw);
@@ -71,7 +70,6 @@ static s32 e1000_read_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset,
static s32 e1000_write_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset,
u16 data);
static void e1000_initialize_hw_bits_80003es2lan(struct e1000_hw *hw);
-static void e1000_release_swfw_sync_80003es2lan(struct e1000_hw *hw, u16 mask);
static s32 e1000_read_mac_addr_80003es2lan(struct e1000_hw *hw);
static void e1000_power_down_phy_copper_80003es2lan(struct e1000_hw *hw);
@@ -302,7 +300,7 @@ static s32 e1000_acquire_phy_80003es2lan(struct e1000_hw *hw)
DEBUGFUNC("e1000_acquire_phy_80003es2lan");
mask = hw->bus.func ? E1000_SWFW_PHY1_SM : E1000_SWFW_PHY0_SM;
- return e1000_acquire_swfw_sync_80003es2lan(hw, mask);
+ return e1000_acquire_swfw_sync(hw, mask);
}
/**
@@ -318,7 +316,7 @@ static void e1000_release_phy_80003es2lan(struct e1000_hw *hw)
DEBUGFUNC("e1000_release_phy_80003es2lan");
mask = hw->bus.func ? E1000_SWFW_PHY1_SM : E1000_SWFW_PHY0_SM;
- e1000_release_swfw_sync_80003es2lan(hw, mask);
+ e1000_release_swfw_sync(hw, mask);
}
/**
@@ -336,7 +334,7 @@ static s32 e1000_acquire_mac_csr_80003es2lan(struct e1000_hw *hw)
mask = E1000_SWFW_CSR_SM;
- return e1000_acquire_swfw_sync_80003es2lan(hw, mask);
+ return e1000_acquire_swfw_sync(hw, mask);
}
/**
@@ -353,7 +351,7 @@ static void e1000_release_mac_csr_80003es2lan(struct e1000_hw *hw)
mask = E1000_SWFW_CSR_SM;
- e1000_release_swfw_sync_80003es2lan(hw, mask);
+ e1000_release_swfw_sync(hw, mask);
}
/**
@@ -368,14 +366,14 @@ static s32 e1000_acquire_nvm_80003es2lan(struct e1000_hw *hw)
DEBUGFUNC("e1000_acquire_nvm_80003es2lan");
- ret_val = e1000_acquire_swfw_sync_80003es2lan(hw, E1000_SWFW_EEP_SM);
+ ret_val = e1000_acquire_swfw_sync(hw, E1000_SWFW_EEP_SM);
if (ret_val)
return ret_val;
ret_val = e1000_acquire_nvm_generic(hw);
if (ret_val)
- e1000_release_swfw_sync_80003es2lan(hw, E1000_SWFW_EEP_SM);
+ e1000_release_swfw_sync(hw, E1000_SWFW_EEP_SM);
return ret_val;
}
@@ -391,78 +389,7 @@ static void e1000_release_nvm_80003es2lan(struct e1000_hw *hw)
DEBUGFUNC("e1000_release_nvm_80003es2lan");
e1000_release_nvm_generic(hw);
- e1000_release_swfw_sync_80003es2lan(hw, E1000_SWFW_EEP_SM);
-}
-
-/**
- * e1000_acquire_swfw_sync_80003es2lan - Acquire SW/FW semaphore
- * @hw: pointer to the HW structure
- * @mask: specifies which semaphore to acquire
- *
- * Acquire the SW/FW semaphore to access the PHY or NVM. The mask
- * will also specify which port we're acquiring the lock for.
- **/
-static s32 e1000_acquire_swfw_sync_80003es2lan(struct e1000_hw *hw, u16 mask)
-{
- u32 swfw_sync;
- u32 swmask = mask;
- u32 fwmask = mask << 16;
- s32 i = 0;
- s32 timeout = 50;
-
- DEBUGFUNC("e1000_acquire_swfw_sync_80003es2lan");
-
- while (i < timeout) {
- if (e1000_get_hw_semaphore_generic(hw))
- return -E1000_ERR_SWFW_SYNC;
-
- swfw_sync = E1000_READ_REG(hw, E1000_SW_FW_SYNC);
- if (!(swfw_sync & (fwmask | swmask)))
- break;
-
- /* Firmware currently using resource (fwmask)
- * or other software thread using resource (swmask)
- */
- e1000_put_hw_semaphore_generic(hw);
- msec_delay_irq(5);
- i++;
- }
-
- if (i == timeout) {
- DEBUGOUT("Driver can't access resource, SW_FW_SYNC timeout.\n");
- return -E1000_ERR_SWFW_SYNC;
- }
-
- swfw_sync |= swmask;
- E1000_WRITE_REG(hw, E1000_SW_FW_SYNC, swfw_sync);
-
- e1000_put_hw_semaphore_generic(hw);
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_release_swfw_sync_80003es2lan - Release SW/FW semaphore
- * @hw: pointer to the HW structure
- * @mask: specifies which semaphore to acquire
- *
- * Release the SW/FW semaphore used to access the PHY or NVM. The mask
- * will also specify which port we're releasing the lock for.
- **/
-static void e1000_release_swfw_sync_80003es2lan(struct e1000_hw *hw, u16 mask)
-{
- u32 swfw_sync;
-
- DEBUGFUNC("e1000_release_swfw_sync_80003es2lan");
-
- while (e1000_get_hw_semaphore_generic(hw) != E1000_SUCCESS)
- ; /* Empty */
-
- swfw_sync = E1000_READ_REG(hw, E1000_SW_FW_SYNC);
- swfw_sync &= ~mask;
- E1000_WRITE_REG(hw, E1000_SW_FW_SYNC, swfw_sync);
-
- e1000_put_hw_semaphore_generic(hw);
+ e1000_release_swfw_sync(hw, E1000_SWFW_EEP_SM);
}
/**
diff --git a/freebsd/sys/dev/e1000/e1000_82571.c b/freebsd/sys/dev/e1000/e1000_82571.c
index fdef7284..f84baf92 100644
--- a/freebsd/sys/dev/e1000/e1000_82571.c
+++ b/freebsd/sys/dev/e1000/e1000_82571.c
@@ -73,11 +73,8 @@ static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw);
static s32 e1000_setup_fiber_serdes_link_82571(struct e1000_hw *hw);
static s32 e1000_valid_led_default_82571(struct e1000_hw *hw, u16 *data);
static void e1000_clear_hw_cntrs_82571(struct e1000_hw *hw);
-static s32 e1000_get_hw_semaphore_82571(struct e1000_hw *hw);
static s32 e1000_fix_nvm_checksum_82571(struct e1000_hw *hw);
static s32 e1000_get_phy_id_82571(struct e1000_hw *hw);
-static void e1000_put_hw_semaphore_82571(struct e1000_hw *hw);
-static void e1000_put_hw_semaphore_82573(struct e1000_hw *hw);
static s32 e1000_get_hw_semaphore_82574(struct e1000_hw *hw);
static void e1000_put_hw_semaphore_82574(struct e1000_hw *hw);
static s32 e1000_set_d0_lplu_state_82574(struct e1000_hw *hw,
@@ -128,8 +125,8 @@ static s32 e1000_init_phy_params_82571(struct e1000_hw *hw)
phy->ops.get_cable_length = e1000_get_cable_length_igp_2;
phy->ops.read_reg = e1000_read_phy_reg_igp;
phy->ops.write_reg = e1000_write_phy_reg_igp;
- phy->ops.acquire = e1000_get_hw_semaphore_82571;
- phy->ops.release = e1000_put_hw_semaphore_82571;
+ phy->ops.acquire = e1000_get_hw_semaphore;
+ phy->ops.release = e1000_put_hw_semaphore;
break;
case e1000_82573:
phy->type = e1000_phy_m88;
@@ -141,12 +138,11 @@ static s32 e1000_init_phy_params_82571(struct e1000_hw *hw)
phy->ops.get_cable_length = e1000_get_cable_length_m88;
phy->ops.read_reg = e1000_read_phy_reg_m88;
phy->ops.write_reg = e1000_write_phy_reg_m88;
- phy->ops.acquire = e1000_get_hw_semaphore_82571;
- phy->ops.release = e1000_put_hw_semaphore_82571;
+ phy->ops.acquire = e1000_get_hw_semaphore;
+ phy->ops.release = e1000_put_hw_semaphore;
break;
case e1000_82574:
case e1000_82583:
- E1000_MUTEX_INIT(&hw->dev_spec._82571.swflag_mutex);
phy->type = e1000_phy_bm;
phy->ops.get_cfg_done = e1000_get_cfg_done_generic;
@@ -509,99 +505,21 @@ static s32 e1000_get_phy_id_82571(struct e1000_hw *hw)
}
/**
- * e1000_get_hw_semaphore_82571 - Acquire hardware semaphore
- * @hw: pointer to the HW structure
- *
- * Acquire the HW semaphore to access the PHY or NVM
- **/
-static s32 e1000_get_hw_semaphore_82571(struct e1000_hw *hw)
-{
- u32 swsm;
- s32 sw_timeout = hw->nvm.word_size + 1;
- s32 fw_timeout = hw->nvm.word_size + 1;
- s32 i = 0;
-
- DEBUGFUNC("e1000_get_hw_semaphore_82571");
-
- /* If we have timedout 3 times on trying to acquire
- * the inter-port SMBI semaphore, there is old code
- * operating on the other port, and it is not
- * releasing SMBI. Modify the number of times that
- * we try for the semaphore to interwork with this
- * older code.
- */
- if (hw->dev_spec._82571.smb_counter > 2)
- sw_timeout = 1;
-
- /* Get the SW semaphore */
- while (i < sw_timeout) {
- swsm = E1000_READ_REG(hw, E1000_SWSM);
- if (!(swsm & E1000_SWSM_SMBI))
- break;
-
- usec_delay(50);
- i++;
- }
-
- if (i == sw_timeout) {
- DEBUGOUT("Driver can't access device - SMBI bit is set.\n");
- hw->dev_spec._82571.smb_counter++;
- }
- /* Get the FW semaphore. */
- for (i = 0; i < fw_timeout; i++) {
- swsm = E1000_READ_REG(hw, E1000_SWSM);
- E1000_WRITE_REG(hw, E1000_SWSM, swsm | E1000_SWSM_SWESMBI);
-
- /* Semaphore acquired if bit latched */
- if (E1000_READ_REG(hw, E1000_SWSM) & E1000_SWSM_SWESMBI)
- break;
-
- usec_delay(50);
- }
-
- if (i == fw_timeout) {
- /* Release semaphores */
- e1000_put_hw_semaphore_82571(hw);
- DEBUGOUT("Driver can't access the NVM\n");
- return -E1000_ERR_NVM;
- }
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_put_hw_semaphore_82571 - Release hardware semaphore
- * @hw: pointer to the HW structure
- *
- * Release hardware semaphore used to access the PHY or NVM
- **/
-static void e1000_put_hw_semaphore_82571(struct e1000_hw *hw)
-{
- u32 swsm;
-
- DEBUGFUNC("e1000_put_hw_semaphore_generic");
-
- swsm = E1000_READ_REG(hw, E1000_SWSM);
-
- swsm &= ~(E1000_SWSM_SMBI | E1000_SWSM_SWESMBI);
-
- E1000_WRITE_REG(hw, E1000_SWSM, swsm);
-}
-
-/**
- * e1000_get_hw_semaphore_82573 - Acquire hardware semaphore
+ * e1000_get_hw_semaphore_82574 - Acquire hardware semaphore
* @hw: pointer to the HW structure
*
* Acquire the HW semaphore during reset.
*
**/
-static s32 e1000_get_hw_semaphore_82573(struct e1000_hw *hw)
+static s32
+e1000_get_hw_semaphore_82574(struct e1000_hw *hw)
{
u32 extcnf_ctrl;
s32 i = 0;
-
+ /* XXX assert that mutex is held */
DEBUGFUNC("e1000_get_hw_semaphore_82573");
+ ASSERT_CTX_LOCK_HELD(hw);
extcnf_ctrl = E1000_READ_REG(hw, E1000_EXTCNF_CTRL);
do {
extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP;
@@ -617,7 +535,7 @@ static s32 e1000_get_hw_semaphore_82573(struct e1000_hw *hw)
if (i == MDIO_OWNERSHIP_TIMEOUT) {
/* Release semaphores */
- e1000_put_hw_semaphore_82573(hw);
+ e1000_put_hw_semaphore_82574(hw);
DEBUGOUT("Driver can't access the PHY\n");
return -E1000_ERR_PHY;
}
@@ -626,17 +544,18 @@ static s32 e1000_get_hw_semaphore_82573(struct e1000_hw *hw)
}
/**
- * e1000_put_hw_semaphore_82573 - Release hardware semaphore
+ * e1000_put_hw_semaphore_82574 - Release hardware semaphore
* @hw: pointer to the HW structure
*
* Release hardware semaphore used during reset.
*
**/
-static void e1000_put_hw_semaphore_82573(struct e1000_hw *hw)
+static void
+e1000_put_hw_semaphore_82574(struct e1000_hw *hw)
{
u32 extcnf_ctrl;
- DEBUGFUNC("e1000_put_hw_semaphore_82573");
+ DEBUGFUNC("e1000_put_hw_semaphore_82574");
extcnf_ctrl = E1000_READ_REG(hw, E1000_EXTCNF_CTRL);
extcnf_ctrl &= ~E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP;
@@ -644,41 +563,6 @@ static void e1000_put_hw_semaphore_82573(struct e1000_hw *hw)
}
/**
- * e1000_get_hw_semaphore_82574 - Acquire hardware semaphore
- * @hw: pointer to the HW structure
- *
- * Acquire the HW semaphore to access the PHY or NVM.
- *
- **/
-static s32 e1000_get_hw_semaphore_82574(struct e1000_hw *hw)
-{
- s32 ret_val;
-
- DEBUGFUNC("e1000_get_hw_semaphore_82574");
-
- E1000_MUTEX_LOCK(&hw->dev_spec._82571.swflag_mutex);
- ret_val = e1000_get_hw_semaphore_82573(hw);
- if (ret_val)
- E1000_MUTEX_UNLOCK(&hw->dev_spec._82571.swflag_mutex);
- return ret_val;
-}
-
-/**
- * e1000_put_hw_semaphore_82574 - Release hardware semaphore
- * @hw: pointer to the HW structure
- *
- * Release hardware semaphore used to access the PHY or NVM
- *
- **/
-static void e1000_put_hw_semaphore_82574(struct e1000_hw *hw)
-{
- DEBUGFUNC("e1000_put_hw_semaphore_82574");
-
- e1000_put_hw_semaphore_82573(hw);
- E1000_MUTEX_UNLOCK(&hw->dev_spec._82571.swflag_mutex);
-}
-
-/**
* e1000_set_d0_lplu_state_82574 - Set Low Power Linkup D0 state
* @hw: pointer to the HW structure
* @active: TRUE to enable LPLU, FALSE to disable
@@ -749,7 +633,7 @@ static s32 e1000_acquire_nvm_82571(struct e1000_hw *hw)
DEBUGFUNC("e1000_acquire_nvm_82571");
- ret_val = e1000_get_hw_semaphore_82571(hw);
+ ret_val = e1000_get_hw_semaphore(hw);
if (ret_val)
return ret_val;
@@ -762,7 +646,7 @@ static s32 e1000_acquire_nvm_82571(struct e1000_hw *hw)
}
if (ret_val)
- e1000_put_hw_semaphore_82571(hw);
+ e1000_put_hw_semaphore(hw);
return ret_val;
}
@@ -778,7 +662,7 @@ static void e1000_release_nvm_82571(struct e1000_hw *hw)
DEBUGFUNC("e1000_release_nvm_82571");
e1000_release_nvm_generic(hw);
- e1000_put_hw_semaphore_82571(hw);
+ e1000_put_hw_semaphore(hw);
}
/**
@@ -1095,8 +979,6 @@ static s32 e1000_reset_hw_82571(struct e1000_hw *hw)
*/
switch (hw->mac.type) {
case e1000_82573:
- ret_val = e1000_get_hw_semaphore_82573(hw);
- break;
case e1000_82574:
case e1000_82583:
ret_val = e1000_get_hw_semaphore_82574(hw);
@@ -1113,10 +995,6 @@ static s32 e1000_reset_hw_82571(struct e1000_hw *hw)
/* Must release MDIO ownership and mutex after MAC reset. */
switch (hw->mac.type) {
case e1000_82573:
- /* Release mutex only if the hw semaphore is acquired */
- if (!ret_val)
- e1000_put_hw_semaphore_82573(hw);
- break;
case e1000_82574:
case e1000_82583:
/* Release mutex only if the hw semaphore is acquired */
@@ -1124,6 +1002,7 @@ static s32 e1000_reset_hw_82571(struct e1000_hw *hw)
e1000_put_hw_semaphore_82574(hw);
break;
default:
+ /* we didn't get the semaphore no need to put it */
break;
}
diff --git a/freebsd/sys/dev/e1000/e1000_82575.c b/freebsd/sys/dev/e1000/e1000_82575.c
index bffa1117..0de11ef5 100644
--- a/freebsd/sys/dev/e1000/e1000_82575.c
+++ b/freebsd/sys/dev/e1000/e1000_82575.c
@@ -82,11 +82,9 @@ static s32 e1000_valid_led_default_82575(struct e1000_hw *hw, u16 *data);
static s32 e1000_write_phy_reg_sgmii_82575(struct e1000_hw *hw,
u32 offset, u16 data);
static void e1000_clear_hw_cntrs_82575(struct e1000_hw *hw);
-static s32 e1000_acquire_swfw_sync_82575(struct e1000_hw *hw, u16 mask);
static s32 e1000_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw,
u16 *speed, u16 *duplex);
static s32 e1000_get_phy_id_82575(struct e1000_hw *hw);
-static void e1000_release_swfw_sync_82575(struct e1000_hw *hw, u16 mask);
static bool e1000_sgmii_active_82575(struct e1000_hw *hw);
static s32 e1000_reset_init_script_82575(struct e1000_hw *hw);
static s32 e1000_read_mac_addr_82575(struct e1000_hw *hw);
@@ -514,12 +512,8 @@ static s32 e1000_init_mac_params_82575(struct e1000_hw *hw)
/* link info */
mac->ops.get_link_up_info = e1000_get_link_up_info_82575;
/* acquire SW_FW sync */
- mac->ops.acquire_swfw_sync = e1000_acquire_swfw_sync_82575;
- mac->ops.release_swfw_sync = e1000_release_swfw_sync_82575;
- if (mac->type >= e1000_i210) {
- mac->ops.acquire_swfw_sync = e1000_acquire_swfw_sync_i210;
- mac->ops.release_swfw_sync = e1000_release_swfw_sync_i210;
- }
+ mac->ops.acquire_swfw_sync = e1000_acquire_swfw_sync;
+ mac->ops.release_swfw_sync = e1000_release_swfw_sync;
/* set lan id for port to determine which phy lock to use */
hw->mac.ops.set_lan_id(hw);
@@ -991,7 +985,7 @@ static s32 e1000_acquire_nvm_82575(struct e1000_hw *hw)
DEBUGFUNC("e1000_acquire_nvm_82575");
- ret_val = e1000_acquire_swfw_sync_82575(hw, E1000_SWFW_EEP_SM);
+ ret_val = e1000_acquire_swfw_sync(hw, E1000_SWFW_EEP_SM);
if (ret_val)
goto out;
@@ -1022,7 +1016,7 @@ static s32 e1000_acquire_nvm_82575(struct e1000_hw *hw)
ret_val = e1000_acquire_nvm_generic(hw);
if (ret_val)
- e1000_release_swfw_sync_82575(hw, E1000_SWFW_EEP_SM);
+ e1000_release_swfw_sync(hw, E1000_SWFW_EEP_SM);
out:
return ret_val;
@@ -1041,83 +1035,7 @@ static void e1000_release_nvm_82575(struct e1000_hw *hw)
e1000_release_nvm_generic(hw);
- e1000_release_swfw_sync_82575(hw, E1000_SWFW_EEP_SM);
-}
-
-/**
- * e1000_acquire_swfw_sync_82575 - Acquire SW/FW semaphore
- * @hw: pointer to the HW structure
- * @mask: specifies which semaphore to acquire
- *
- * Acquire the SW/FW semaphore to access the PHY or NVM. The mask
- * will also specify which port we're acquiring the lock for.
- **/
-static s32 e1000_acquire_swfw_sync_82575(struct e1000_hw *hw, u16 mask)
-{
- u32 swfw_sync;
- u32 swmask = mask;
- u32 fwmask = mask << 16;
- s32 ret_val = E1000_SUCCESS;
- s32 i = 0, timeout = 200;
-
- DEBUGFUNC("e1000_acquire_swfw_sync_82575");
-
- while (i < timeout) {
- if (e1000_get_hw_semaphore_generic(hw)) {
- ret_val = -E1000_ERR_SWFW_SYNC;
- goto out;
- }
-
- swfw_sync = E1000_READ_REG(hw, E1000_SW_FW_SYNC);
- if (!(swfw_sync & (fwmask | swmask)))
- break;
-
- /*
- * Firmware currently using resource (fwmask)
- * or other software thread using resource (swmask)
- */
- e1000_put_hw_semaphore_generic(hw);
- msec_delay_irq(5);
- i++;
- }
-
- if (i == timeout) {
- DEBUGOUT("Driver can't access resource, SW_FW_SYNC timeout.\n");
- ret_val = -E1000_ERR_SWFW_SYNC;
- goto out;
- }
-
- swfw_sync |= swmask;
- E1000_WRITE_REG(hw, E1000_SW_FW_SYNC, swfw_sync);
-
- e1000_put_hw_semaphore_generic(hw);
-
-out:
- return ret_val;
-}
-
-/**
- * e1000_release_swfw_sync_82575 - Release SW/FW semaphore
- * @hw: pointer to the HW structure
- * @mask: specifies which semaphore to acquire
- *
- * Release the SW/FW semaphore used to access the PHY or NVM. The mask
- * will also specify which port we're releasing the lock for.
- **/
-static void e1000_release_swfw_sync_82575(struct e1000_hw *hw, u16 mask)
-{
- u32 swfw_sync;
-
- DEBUGFUNC("e1000_release_swfw_sync_82575");
-
- while (e1000_get_hw_semaphore_generic(hw) != E1000_SUCCESS)
- ; /* Empty */
-
- swfw_sync = E1000_READ_REG(hw, E1000_SW_FW_SYNC);
- swfw_sync &= ~mask;
- E1000_WRITE_REG(hw, E1000_SW_FW_SYNC, swfw_sync);
-
- e1000_put_hw_semaphore_generic(hw);
+ e1000_release_swfw_sync(hw, E1000_SWFW_EEP_SM);
}
/**
diff --git a/freebsd/sys/dev/e1000/e1000_hw.h b/freebsd/sys/dev/e1000/e1000_hw.h
index 2c17a022..7e4e7f1a 100644
--- a/freebsd/sys/dev/e1000/e1000_hw.h
+++ b/freebsd/sys/dev/e1000/e1000_hw.h
@@ -944,7 +944,6 @@ struct e1000_dev_spec_82543 {
struct e1000_dev_spec_82571 {
bool laa_is_present;
u32 smb_counter;
- E1000_MUTEX swflag_mutex;
};
struct e1000_dev_spec_80003es2lan {
@@ -968,8 +967,6 @@ enum e1000_ulp_state {
struct e1000_dev_spec_ich8lan {
bool kmrn_lock_loss_workaround_enabled;
struct e1000_shadow_ram shadow_ram[E1000_SHADOW_RAM_WORDS];
- E1000_MUTEX nvm_mutex;
- E1000_MUTEX swflag_mutex;
bool nvm_k1_enabled;
bool disable_k1_off;
bool eee_disable;
diff --git a/freebsd/sys/dev/e1000/e1000_i210.c b/freebsd/sys/dev/e1000/e1000_i210.c
index 5f09e4d2..5ee48810 100644
--- a/freebsd/sys/dev/e1000/e1000_i210.c
+++ b/freebsd/sys/dev/e1000/e1000_i210.c
@@ -40,7 +40,6 @@
static s32 e1000_acquire_nvm_i210(struct e1000_hw *hw);
static void e1000_release_nvm_i210(struct e1000_hw *hw);
-static s32 e1000_get_hw_semaphore_i210(struct e1000_hw *hw);
static s32 e1000_write_nvm_srwr(struct e1000_hw *hw, u16 offset, u16 words,
u16 *data);
static s32 e1000_pool_flash_update_done_i210(struct e1000_hw *hw);
@@ -61,7 +60,7 @@ static s32 e1000_acquire_nvm_i210(struct e1000_hw *hw)
DEBUGFUNC("e1000_acquire_nvm_i210");
- ret_val = e1000_acquire_swfw_sync_i210(hw, E1000_SWFW_EEP_SM);
+ ret_val = e1000_acquire_swfw_sync(hw, E1000_SWFW_EEP_SM);
return ret_val;
}
@@ -77,152 +76,7 @@ static void e1000_release_nvm_i210(struct e1000_hw *hw)
{
DEBUGFUNC("e1000_release_nvm_i210");
- e1000_release_swfw_sync_i210(hw, E1000_SWFW_EEP_SM);
-}
-
-/**
- * e1000_acquire_swfw_sync_i210 - Acquire SW/FW semaphore
- * @hw: pointer to the HW structure
- * @mask: specifies which semaphore to acquire
- *
- * Acquire the SW/FW semaphore to access the PHY or NVM. The mask
- * will also specify which port we're acquiring the lock for.
- **/
-s32 e1000_acquire_swfw_sync_i210(struct e1000_hw *hw, u16 mask)
-{
- u32 swfw_sync;
- u32 swmask = mask;
- u32 fwmask = mask << 16;
- s32 ret_val = E1000_SUCCESS;
- s32 i = 0, timeout = 200; /* FIXME: find real value to use here */
-
- DEBUGFUNC("e1000_acquire_swfw_sync_i210");
-
- while (i < timeout) {
- if (e1000_get_hw_semaphore_i210(hw)) {
- ret_val = -E1000_ERR_SWFW_SYNC;
- goto out;
- }
-
- swfw_sync = E1000_READ_REG(hw, E1000_SW_FW_SYNC);
- if (!(swfw_sync & (fwmask | swmask)))
- break;
-
- /*
- * Firmware currently using resource (fwmask)
- * or other software thread using resource (swmask)
- */
- e1000_put_hw_semaphore_generic(hw);
- msec_delay_irq(5);
- i++;
- }
-
- if (i == timeout) {
- DEBUGOUT("Driver can't access resource, SW_FW_SYNC timeout.\n");
- ret_val = -E1000_ERR_SWFW_SYNC;
- goto out;
- }
-
- swfw_sync |= swmask;
- E1000_WRITE_REG(hw, E1000_SW_FW_SYNC, swfw_sync);
-
- e1000_put_hw_semaphore_generic(hw);
-
-out:
- return ret_val;
-}
-
-/**
- * e1000_release_swfw_sync_i210 - Release SW/FW semaphore
- * @hw: pointer to the HW structure
- * @mask: specifies which semaphore to acquire
- *
- * Release the SW/FW semaphore used to access the PHY or NVM. The mask
- * will also specify which port we're releasing the lock for.
- **/
-void e1000_release_swfw_sync_i210(struct e1000_hw *hw, u16 mask)
-{
- u32 swfw_sync;
-
- DEBUGFUNC("e1000_release_swfw_sync_i210");
-
- while (e1000_get_hw_semaphore_i210(hw) != E1000_SUCCESS)
- ; /* Empty */
-
- swfw_sync = E1000_READ_REG(hw, E1000_SW_FW_SYNC);
- swfw_sync &= ~mask;
- E1000_WRITE_REG(hw, E1000_SW_FW_SYNC, swfw_sync);
-
- e1000_put_hw_semaphore_generic(hw);
-}
-
-/**
- * e1000_get_hw_semaphore_i210 - Acquire hardware semaphore
- * @hw: pointer to the HW structure
- *
- * Acquire the HW semaphore to access the PHY or NVM
- **/
-static s32 e1000_get_hw_semaphore_i210(struct e1000_hw *hw)
-{
- u32 swsm;
- s32 timeout = hw->nvm.word_size + 1;
- s32 i = 0;
-
- DEBUGFUNC("e1000_get_hw_semaphore_i210");
-
- /* Get the SW semaphore */
- while (i < timeout) {
- swsm = E1000_READ_REG(hw, E1000_SWSM);
- if (!(swsm & E1000_SWSM_SMBI))
- break;
-
- usec_delay(50);
- i++;
- }
-
- if (i == timeout) {
- /* In rare circumstances, the SW semaphore may already be held
- * unintentionally. Clear the semaphore once before giving up.
- */
- if (hw->dev_spec._82575.clear_semaphore_once) {
- hw->dev_spec._82575.clear_semaphore_once = FALSE;
- e1000_put_hw_semaphore_generic(hw);
- for (i = 0; i < timeout; i++) {
- swsm = E1000_READ_REG(hw, E1000_SWSM);
- if (!(swsm & E1000_SWSM_SMBI))
- break;
-
- usec_delay(50);
- }
- }
-
- /* If we do not have the semaphore here, we have to give up. */
- if (i == timeout) {
- DEBUGOUT("Driver can't access device - SMBI bit is set.\n");
- return -E1000_ERR_NVM;
- }
- }
-
- /* Get the FW semaphore. */
- for (i = 0; i < timeout; i++) {
- swsm = E1000_READ_REG(hw, E1000_SWSM);
- E1000_WRITE_REG(hw, E1000_SWSM, swsm | E1000_SWSM_SWESMBI);
-
- /* Semaphore acquired if bit latched */
- if (E1000_READ_REG(hw, E1000_SWSM) & E1000_SWSM_SWESMBI)
- break;
-
- usec_delay(50);
- }
-
- if (i == timeout) {
- /* Release semaphores */
- e1000_put_hw_semaphore_generic(hw);
- DEBUGOUT("Driver can't access the NVM\n");
- return -E1000_ERR_NVM;
- }
-
- return E1000_SUCCESS;
+ e1000_release_swfw_sync(hw, E1000_SWFW_EEP_SM);
}
/**
diff --git a/freebsd/sys/dev/e1000/e1000_i210.h b/freebsd/sys/dev/e1000/e1000_i210.h
index c08a0dd7..ed6262b5 100644
--- a/freebsd/sys/dev/e1000/e1000_i210.h
+++ b/freebsd/sys/dev/e1000/e1000_i210.h
@@ -44,8 +44,6 @@ s32 e1000_write_nvm_srwr_i210(struct e1000_hw *hw, u16 offset,
u16 words, u16 *data);
s32 e1000_read_nvm_srrd_i210(struct e1000_hw *hw, u16 offset,
u16 words, u16 *data);
-s32 e1000_acquire_swfw_sync_i210(struct e1000_hw *hw, u16 mask);
-void e1000_release_swfw_sync_i210(struct e1000_hw *hw, u16 mask);
s32 e1000_read_xmdio_reg(struct e1000_hw *hw, u16 addr, u8 dev_addr,
u16 *data);
s32 e1000_write_xmdio_reg(struct e1000_hw *hw, u16 addr, u8 dev_addr,
diff --git a/freebsd/sys/dev/e1000/e1000_ich8lan.c b/freebsd/sys/dev/e1000/e1000_ich8lan.c
index bcd82c47..cbddadd7 100644
--- a/freebsd/sys/dev/e1000/e1000_ich8lan.c
+++ b/freebsd/sys/dev/e1000/e1000_ich8lan.c
@@ -699,9 +699,6 @@ static s32 e1000_init_nvm_params_ich8lan(struct e1000_hw *hw)
dev_spec->shadow_ram[i].value = 0xFFFF;
}
- E1000_MUTEX_INIT(&dev_spec->nvm_mutex);
- E1000_MUTEX_INIT(&dev_spec->swflag_mutex);
-
/* Function Pointers */
nvm->ops.acquire = e1000_acquire_nvm_ich8lan;
nvm->ops.release = e1000_release_nvm_ich8lan;
@@ -1854,7 +1851,7 @@ static s32 e1000_acquire_nvm_ich8lan(struct e1000_hw *hw)
{
DEBUGFUNC("e1000_acquire_nvm_ich8lan");
- E1000_MUTEX_LOCK(&hw->dev_spec.ich8lan.nvm_mutex);
+ ASSERT_CTX_LOCK_HELD(hw);
return E1000_SUCCESS;
}
@@ -1869,9 +1866,7 @@ static void e1000_release_nvm_ich8lan(struct e1000_hw *hw)
{
DEBUGFUNC("e1000_release_nvm_ich8lan");
- E1000_MUTEX_UNLOCK(&hw->dev_spec.ich8lan.nvm_mutex);
-
- return;
+ ASSERT_CTX_LOCK_HELD(hw);
}
/**
@@ -1888,7 +1883,7 @@ static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw)
DEBUGFUNC("e1000_acquire_swflag_ich8lan");
- E1000_MUTEX_LOCK(&hw->dev_spec.ich8lan.swflag_mutex);
+ ASSERT_CTX_LOCK_HELD(hw);
while (timeout) {
extcnf_ctrl = E1000_READ_REG(hw, E1000_EXTCNF_CTRL);
@@ -1929,9 +1924,6 @@ static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw)
}
out:
- if (ret_val)
- E1000_MUTEX_UNLOCK(&hw->dev_spec.ich8lan.swflag_mutex);
-
return ret_val;
}
@@ -1956,10 +1948,6 @@ static void e1000_release_swflag_ich8lan(struct e1000_hw *hw)
} else {
DEBUGOUT("Semaphore unexpectedly released by sw/fw/hw\n");
}
-
- E1000_MUTEX_UNLOCK(&hw->dev_spec.ich8lan.swflag_mutex);
-
- return;
}
/**
@@ -5034,8 +5022,6 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw)
E1000_WRITE_REG(hw, E1000_FEXTNVM3, reg);
}
- if (!ret_val)
- E1000_MUTEX_UNLOCK(&hw->dev_spec.ich8lan.swflag_mutex);
if (ctrl & E1000_CTRL_PHY_RST) {
ret_val = hw->phy.ops.get_cfg_done(hw);
diff --git a/freebsd/sys/dev/e1000/e1000_mac.c b/freebsd/sys/dev/e1000/e1000_mac.c
index 581659be..7a46ca5a 100644
--- a/freebsd/sys/dev/e1000/e1000_mac.c
+++ b/freebsd/sys/dev/e1000/e1000_mac.c
@@ -1710,76 +1710,6 @@ s32 e1000_get_speed_and_duplex_fiber_serdes_generic(struct e1000_hw E1000_UNUSED
}
/**
- * e1000_get_hw_semaphore_generic - Acquire hardware semaphore
- * @hw: pointer to the HW structure
- *
- * Acquire the HW semaphore to access the PHY or NVM
- **/
-s32 e1000_get_hw_semaphore_generic(struct e1000_hw *hw)
-{
- u32 swsm;
- s32 timeout = hw->nvm.word_size + 1;
- s32 i = 0;
-
- DEBUGFUNC("e1000_get_hw_semaphore_generic");
-
- /* Get the SW semaphore */
- while (i < timeout) {
- swsm = E1000_READ_REG(hw, E1000_SWSM);
- if (!(swsm & E1000_SWSM_SMBI))
- break;
-
- usec_delay(50);
- i++;
- }
-
- if (i == timeout) {
- DEBUGOUT("Driver can't access device - SMBI bit is set.\n");
- return -E1000_ERR_NVM;
- }
-
- /* Get the FW semaphore. */
- for (i = 0; i < timeout; i++) {
- swsm = E1000_READ_REG(hw, E1000_SWSM);
- E1000_WRITE_REG(hw, E1000_SWSM, swsm | E1000_SWSM_SWESMBI);
-
- /* Semaphore acquired if bit latched */
- if (E1000_READ_REG(hw, E1000_SWSM) & E1000_SWSM_SWESMBI)
- break;
-
- usec_delay(50);
- }
-
- if (i == timeout) {
- /* Release semaphores */
- e1000_put_hw_semaphore_generic(hw);
- DEBUGOUT("Driver can't access the NVM\n");
- return -E1000_ERR_NVM;
- }
-
- return E1000_SUCCESS;
-}
-
-/**
- * e1000_put_hw_semaphore_generic - Release hardware semaphore
- * @hw: pointer to the HW structure
- *
- * Release hardware semaphore used to access the PHY or NVM
- **/
-void e1000_put_hw_semaphore_generic(struct e1000_hw *hw)
-{
- u32 swsm;
-
- DEBUGFUNC("e1000_put_hw_semaphore_generic");
-
- swsm = E1000_READ_REG(hw, E1000_SWSM);
-
- swsm &= ~(E1000_SWSM_SMBI | E1000_SWSM_SWESMBI);
-
- E1000_WRITE_REG(hw, E1000_SWSM, swsm);
-}
-
-/**
* e1000_get_auto_rd_done_generic - Check for auto read completion
* @hw: pointer to the HW structure
*
@@ -2254,3 +2184,181 @@ s32 e1000_write_8bit_ctrl_reg_generic(struct e1000_hw *hw, u32 reg,
return E1000_SUCCESS;
}
+
+/**
+ * e1000_get_hw_semaphore - Acquire hardware semaphore
+ * @hw: pointer to the HW structure
+ *
+ * Acquire the HW semaphore to access the PHY or NVM
+ **/
+s32 e1000_get_hw_semaphore(struct e1000_hw *hw)
+{
+ u32 swsm;
+ s32 fw_timeout = hw->nvm.word_size + 1;
+ s32 sw_timeout = hw->nvm.word_size + 1;
+ s32 i = 0;
+
+ DEBUGFUNC("e1000_get_hw_semaphore");
+
+ /* _82571 */
+ /* If we have timedout 3 times on trying to acquire
+ * the inter-port SMBI semaphore, there is old code
+ * operating on the other port, and it is not
+ * releasing SMBI. Modify the number of times that
+ * we try for the semaphore to interwork with this
+ * older code.
+ */
+ if (hw->dev_spec._82571.smb_counter > 2)
+ sw_timeout = 1;
+
+
+ /* Get the SW semaphore */
+ while (i < sw_timeout) {
+ swsm = E1000_READ_REG(hw, E1000_SWSM);
+ if (!(swsm & E1000_SWSM_SMBI))
+ break;
+
+ usec_delay(50);
+ i++;
+ }
+
+ if (i == sw_timeout) {
+ DEBUGOUT("Driver can't access device - SMBI bit is set.\n");
+ hw->dev_spec._82571.smb_counter++;
+ }
+
+ /* In rare circumstances, the SW semaphore may already be held
+ * unintentionally. Clear the semaphore once before giving up.
+ */
+ if (hw->dev_spec._82575.clear_semaphore_once) {
+ hw->dev_spec._82575.clear_semaphore_once = FALSE;
+ e1000_put_hw_semaphore(hw);
+ for (i = 0; i < fw_timeout; i++) {
+ swsm = E1000_READ_REG(hw, E1000_SWSM);
+ if (!(swsm & E1000_SWSM_SMBI))
+ break;
+
+ usec_delay(50);
+ }
+ }
+
+ /* Get the FW semaphore. */
+ for (i = 0; i < fw_timeout; i++) {
+ swsm = E1000_READ_REG(hw, E1000_SWSM);
+ E1000_WRITE_REG(hw, E1000_SWSM, swsm | E1000_SWSM_SWESMBI);
+
+ /* Semaphore acquired if bit latched */
+ if (E1000_READ_REG(hw, E1000_SWSM) & E1000_SWSM_SWESMBI)
+ break;
+
+ usec_delay(50);
+ }
+
+ if (i == fw_timeout) {
+ /* Release semaphores */
+ e1000_put_hw_semaphore(hw);
+ DEBUGOUT("Driver can't access the NVM\n");
+ return -E1000_ERR_NVM;
+ }
+
+ return E1000_SUCCESS;
+}
+
+/**
+ * e1000_put_hw_semaphore - Release hardware semaphore
+ * @hw: pointer to the HW structure
+ *
+ * Release hardware semaphore used to access the PHY or NVM
+ **/
+void e1000_put_hw_semaphore(struct e1000_hw *hw)
+{
+ u32 swsm;
+
+ DEBUGFUNC("e1000_put_hw_semaphore");
+
+ swsm = E1000_READ_REG(hw, E1000_SWSM);
+
+ swsm &= ~(E1000_SWSM_SMBI | E1000_SWSM_SWESMBI);
+
+ E1000_WRITE_REG(hw, E1000_SWSM, swsm);
+}
+
+
+/**
+ * e1000_acquire_swfw_sync - Acquire SW/FW semaphore
+ * @hw: pointer to the HW structure
+ * @mask: specifies which semaphore to acquire
+ *
+ * Acquire the SW/FW semaphore to access the PHY or NVM. The mask
+ * will also specify which port we're acquiring the lock for.
+ **/
+s32
+e1000_acquire_swfw_sync(struct e1000_hw *hw, u16 mask)
+{
+ u32 swfw_sync;
+ u32 swmask = mask;
+ u32 fwmask = mask << 16;
+ s32 ret_val = E1000_SUCCESS;
+ s32 i = 0, timeout = 200;
+
+ DEBUGFUNC("e1000_acquire_swfw_sync");
+ ASSERT_NO_LOCKS();
+ while (i < timeout) {
+ if (e1000_get_hw_semaphore(hw)) {
+ ret_val = -E1000_ERR_SWFW_SYNC;
+ goto out;
+ }
+
+ swfw_sync = E1000_READ_REG(hw, E1000_SW_FW_SYNC);
+ if (!(swfw_sync & (fwmask | swmask)))
+ break;
+
+ /*
+ * Firmware currently using resource (fwmask)
+ * or other software thread using resource (swmask)
+ */
+ e1000_put_hw_semaphore(hw);
+ msec_delay_irq(5);
+ i++;
+ }
+
+ if (i == timeout) {
+ DEBUGOUT("Driver can't access resource, SW_FW_SYNC timeout.\n");
+ ret_val = -E1000_ERR_SWFW_SYNC;
+ goto out;
+ }
+
+ swfw_sync |= swmask;
+ E1000_WRITE_REG(hw, E1000_SW_FW_SYNC, swfw_sync);
+
+ e1000_put_hw_semaphore(hw);
+
+out:
+ return ret_val;
+}
+
+/**
+ * e1000_release_swfw_sync - Release SW/FW semaphore
+ * @hw: pointer to the HW structure
+ * @mask: specifies which semaphore to acquire
+ *
+ * Release the SW/FW semaphore used to access the PHY or NVM. The mask
+ * will also specify which port we're releasing the lock for.
+ **/
+void
+e1000_release_swfw_sync(struct e1000_hw *hw, u16 mask)
+{
+ u32 swfw_sync;
+
+ DEBUGFUNC("e1000_release_swfw_sync");
+
+ while (e1000_get_hw_semaphore(hw) != E1000_SUCCESS)
+ ; /* Empty */
+
+ swfw_sync = E1000_READ_REG(hw, E1000_SW_FW_SYNC);
+ swfw_sync &= ~mask;
+ E1000_WRITE_REG(hw, E1000_SW_FW_SYNC, swfw_sync);
+
+ e1000_put_hw_semaphore(hw);
+}
+
diff --git a/freebsd/sys/dev/e1000/e1000_mac.h b/freebsd/sys/dev/e1000/e1000_mac.h
index cb8da246..66f94595 100644
--- a/freebsd/sys/dev/e1000/e1000_mac.h
+++ b/freebsd/sys/dev/e1000/e1000_mac.h
@@ -61,7 +61,6 @@ s32 e1000_get_bus_info_pci_generic(struct e1000_hw *hw);
s32 e1000_get_bus_info_pcie_generic(struct e1000_hw *hw);
void e1000_set_lan_id_single_port(struct e1000_hw *hw);
void e1000_set_lan_id_multi_port_pci(struct e1000_hw *hw);
-s32 e1000_get_hw_semaphore_generic(struct e1000_hw *hw);
s32 e1000_get_speed_and_duplex_copper_generic(struct e1000_hw *hw, u16 *speed,
u16 *duplex);
s32 e1000_get_speed_and_duplex_fiber_serdes_generic(struct e1000_hw *hw,
@@ -86,11 +85,15 @@ void e1000_clear_hw_cntrs_base_generic(struct e1000_hw *hw);
void e1000_clear_vfta_generic(struct e1000_hw *hw);
void e1000_init_rx_addrs_generic(struct e1000_hw *hw, u16 rar_count);
void e1000_pcix_mmrbc_workaround_generic(struct e1000_hw *hw);
-void e1000_put_hw_semaphore_generic(struct e1000_hw *hw);
s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw);
void e1000_reset_adaptive_generic(struct e1000_hw *hw);
void e1000_set_pcie_no_snoop_generic(struct e1000_hw *hw, u32 no_snoop);
void e1000_update_adaptive_generic(struct e1000_hw *hw);
void e1000_write_vfta_generic(struct e1000_hw *hw, u32 offset, u32 value);
+s32 e1000_get_hw_semaphore(struct e1000_hw *hw);
+void e1000_put_hw_semaphore(struct e1000_hw *hw);
+s32 e1000_acquire_swfw_sync(struct e1000_hw *hw, u16 mask);
+void e1000_release_swfw_sync(struct e1000_hw *hw, u16 mask);
+
#endif
diff --git a/freebsd/sys/dev/e1000/e1000_osdep.h b/freebsd/sys/dev/e1000/e1000_osdep.h
index d9f956f3..55348785 100644
--- a/freebsd/sys/dev/e1000/e1000_osdep.h
+++ b/freebsd/sys/dev/e1000/e1000_osdep.h
@@ -40,6 +40,7 @@
#include <sys/types.h>
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/proc.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/mbuf.h>
@@ -48,6 +49,14 @@
#include <sys/malloc.h>
#include <sys/kernel.h>
#include <sys/bus.h>
+
+#include <net/ethernet.h>
+#include <net/if.h>
+#include <net/if_var.h>
+#include <net/iflib.h>
+
+
+
#include <machine/bus.h>
#include <sys/rman.h>
#include <machine/resource.h>
@@ -59,11 +68,40 @@
#define ASSERT(x) if(!(x)) panic("EM: x")
+#define us_scale(x) max(1, (x/(1000000/hz)))
+static inline int
+ms_scale(int x) {
+ if (hz == 1000) {
+ return (x);
+ } else if (hz > 1000) {
+ return (x*(hz/1000));
+ } else {
+ return (max(1, x/(1000/hz)));
+ }
+}
+
+static inline void
+safe_pause_us(int x) {
+ if (cold) {
+ DELAY(x);
+ } else {
+ pause("e1000_delay", max(1, x/(1000000/hz)));
+ }
+}
+
+static inline void
+safe_pause_ms(int x) {
+ if (cold) {
+ DELAY(x*1000);
+ } else {
+ pause("e1000_delay", ms_scale(x));
+ }
+}
-#define usec_delay(x) DELAY(x)
+#define usec_delay(x) safe_pause_us(x)
#define usec_delay_irq(x) usec_delay(x)
-#define msec_delay(x) DELAY(1000*(x))
-#define msec_delay_irq(x) DELAY(1000*(x))
+#define msec_delay(x) safe_pause_ms(x)
+#define msec_delay_irq(x) msec_delay(x)
/* Enable/disable debugging statements in shared code */
#define DBG 0
@@ -82,16 +120,6 @@
#define CMD_MEM_WRT_INVALIDATE 0x0010 /* BIT_4 */
#define PCI_COMMAND_REGISTER PCIR_COMMAND
-/* Mutex used in the shared code */
-#define E1000_MUTEX struct mtx
-#define E1000_MUTEX_INIT(mutex) mtx_init((mutex), #mutex, \
- MTX_NETWORK_LOCK, \
- MTX_DEF | MTX_DUPOK)
-#define E1000_MUTEX_DESTROY(mutex) mtx_destroy(mutex)
-#define E1000_MUTEX_LOCK(mutex) mtx_lock(mutex)
-#define E1000_MUTEX_TRYLOCK(mutex) mtx_trylock(mutex)
-#define E1000_MUTEX_UNLOCK(mutex) mtx_unlock(mutex)
-
typedef uint64_t u64;
typedef uint32_t u32;
typedef uint16_t u16;
@@ -117,6 +145,12 @@ typedef int8_t s8;
#endif
#endif /*__FreeBSD_version < 800000 */
+#ifdef INVARIANTS
+#define ASSERT_CTX_LOCK_HELD(hw) (sx_assert(iflib_ctx_lock_get(((struct e1000_osdep *)hw->back)->ctx), SX_XLOCKED))
+#else
+#define ASSERT_CTX_LOCK_HELD(hw)
+#endif
+
#if defined(__i386__) || defined(__amd64__)
static __inline
void prefetch(void *x)
@@ -136,6 +170,7 @@ struct e1000_osdep
bus_space_tag_t flash_bus_space_tag;
bus_space_handle_t flash_bus_space_handle;
device_t dev;
+ if_ctx_t ctx;
};
#define E1000_REGISTER(hw, reg) (((hw)->mac.type >= e1000_82543) \
@@ -217,5 +252,22 @@ struct e1000_osdep
bus_space_write_2(((struct e1000_osdep *)(hw)->back)->flash_bus_space_tag, \
((struct e1000_osdep *)(hw)->back)->flash_bus_space_handle, reg, value)
+
+#if defined(INVARIANTS)
+#include <sys/proc.h>
+
+#define ASSERT_NO_LOCKS() \
+ do { \
+ int unknown_locks = curthread->td_locks - mtx_owned(&Giant); \
+ if (unknown_locks > 0) { \
+ WITNESS_WARN(WARN_GIANTOK|WARN_SLEEPOK|WARN_PANIC, NULL, "unexpected non-sleepable lock"); \
+ } \
+ MPASS(curthread->td_rw_rlocks == 0); \
+ MPASS(curthread->td_lk_slocks == 0); \
+ } while (0)
+#else
+#define ASSERT_NO_LOCKS()
+#endif
+
#endif /* _FREEBSD_OS_H_ */
diff --git a/freebsd/sys/dev/e1000/em_txrx.c b/freebsd/sys/dev/e1000/em_txrx.c
index 92b4a5f4..8157c9ce 100644
--- a/freebsd/sys/dev/e1000/em_txrx.c
+++ b/freebsd/sys/dev/e1000/em_txrx.c
@@ -70,25 +70,25 @@ static int em_determine_rsstype(u32 pkt_info);
extern int em_intr(void *arg);
struct if_txrx em_txrx = {
- em_isc_txd_encap,
- em_isc_txd_flush,
- em_isc_txd_credits_update,
- em_isc_rxd_available,
- em_isc_rxd_pkt_get,
- em_isc_rxd_refill,
- em_isc_rxd_flush,
- em_intr
+ .ift_txd_encap = em_isc_txd_encap,
+ .ift_txd_flush = em_isc_txd_flush,
+ .ift_txd_credits_update = em_isc_txd_credits_update,
+ .ift_rxd_available = em_isc_rxd_available,
+ .ift_rxd_pkt_get = em_isc_rxd_pkt_get,
+ .ift_rxd_refill = em_isc_rxd_refill,
+ .ift_rxd_flush = em_isc_rxd_flush,
+ .ift_legacy_intr = em_intr
};
struct if_txrx lem_txrx = {
- em_isc_txd_encap,
- em_isc_txd_flush,
- em_isc_txd_credits_update,
- lem_isc_rxd_available,
- lem_isc_rxd_pkt_get,
- lem_isc_rxd_refill,
- em_isc_rxd_flush,
- em_intr
+ .ift_txd_encap = em_isc_txd_encap,
+ .ift_txd_flush = em_isc_txd_flush,
+ .ift_txd_credits_update = em_isc_txd_credits_update,
+ .ift_rxd_available = lem_isc_rxd_available,
+ .ift_rxd_pkt_get = lem_isc_rxd_pkt_get,
+ .ift_rxd_refill = lem_isc_rxd_refill,
+ .ift_rxd_flush = em_isc_rxd_flush,
+ .ift_legacy_intr = em_intr
};
extern if_shared_ctx_t em_sctx;
@@ -403,7 +403,7 @@ em_isc_txd_encap(void *arg, if_pkt_info_t pi)
* needs End Of Packet (EOP)
* and Report Status (RS)
*/
- if (txd_flags) {
+ if (txd_flags && nsegs) {
txr->tx_rsq[txr->tx_rs_pidx] = pidx_last;
DPRINTF(iflib_get_dev(sc->ctx), "setting to RS on %d rs_pidx %d first: %d\n", pidx_last, txr->tx_rs_pidx, first);
txr->tx_rs_pidx = (txr->tx_rs_pidx+1) & (ntxd-1);
diff --git a/freebsd/sys/dev/e1000/if_em.c b/freebsd/sys/dev/e1000/if_em.c
index 5150eaea..72711a6e 100644
--- a/freebsd/sys/dev/e1000/if_em.c
+++ b/freebsd/sys/dev/e1000/if_em.c
@@ -738,7 +738,7 @@ em_if_attach_pre(if_ctx_t ctx)
return (ENXIO);
}
- adapter->ctx = ctx;
+ adapter->ctx = adapter->osdep.ctx = ctx;
adapter->dev = adapter->osdep.dev = dev;
scctx = adapter->shared = iflib_get_softc_ctx(ctx);
adapter->media = iflib_get_media(ctx);
@@ -1686,13 +1686,6 @@ em_if_timer(if_ctx_t ctx, uint16_t qid)
return;
iflib_admin_intr_deferred(ctx);
- /* Reset LAA into RAR[0] on 82571 */
- if ((adapter->hw.mac.type == e1000_82571) &&
- e1000_get_laa_state_82571(&adapter->hw))
- e1000_rar_set(&adapter->hw, adapter->hw.mac.addr, 0);
-
- if (adapter->hw.mac.type < em_mac_min)
- lem_smartspeed(adapter);
/* Mask to use in the irq trigger */
if (adapter->intr_type == IFLIB_INTR_MSIX) {
@@ -1803,6 +1796,14 @@ em_if_update_admin_status(if_ctx_t ctx)
}
em_update_stats_counters(adapter);
+ /* Reset LAA into RAR[0] on 82571 */
+ if ((adapter->hw.mac.type == e1000_82571) &&
+ e1000_get_laa_state_82571(&adapter->hw))
+ e1000_rar_set(&adapter->hw, adapter->hw.mac.addr, 0);
+
+ if (adapter->hw.mac.type < em_mac_min)
+ lem_smartspeed(adapter);
+
E1000_WRITE_REG(&adapter->hw, E1000_IMS, EM_MSIX_LINK | E1000_IMS_LSC);
}
diff --git a/freebsd/sys/dev/e1000/igb_txrx.c b/freebsd/sys/dev/e1000/igb_txrx.c
index 05b2fff2..3a56a496 100644
--- a/freebsd/sys/dev/e1000/igb_txrx.c
+++ b/freebsd/sys/dev/e1000/igb_txrx.c
@@ -64,14 +64,14 @@ extern void igb_if_enable_intr(if_ctx_t ctx);
extern int em_intr(void *arg);
struct if_txrx igb_txrx = {
- igb_isc_txd_encap,
- igb_isc_txd_flush,
- igb_isc_txd_credits_update,
- igb_isc_rxd_available,
- igb_isc_rxd_pkt_get,
- igb_isc_rxd_refill,
- igb_isc_rxd_flush,
- em_intr
+ .ift_txd_encap = igb_isc_txd_encap,
+ .ift_txd_flush = igb_isc_txd_flush,
+ .ift_txd_credits_update = igb_isc_txd_credits_update,
+ .ift_rxd_available = igb_isc_rxd_available,
+ .ift_rxd_pkt_get = igb_isc_rxd_pkt_get,
+ .ift_rxd_refill = igb_isc_rxd_refill,
+ .ift_rxd_flush = igb_isc_rxd_flush,
+ .ift_legacy_intr = em_intr
};
extern if_shared_ctx_t em_sctx;
diff --git a/freebsd/sys/dev/evdev/uinput.c b/freebsd/sys/dev/evdev/uinput.c
index f1f812cc..3b332d1f 100644
--- a/freebsd/sys/dev/evdev/uinput.c
+++ b/freebsd/sys/dev/evdev/uinput.c
@@ -606,6 +606,15 @@ uinput_ioctl_sub(struct uinput_cdev_state *state, u_long cmd, caddr_t data)
evdev_set_phys(state->ucs_evdev, buf);
return (0);
+ case UI_SET_BSDUNIQ:
+ if (state->ucs_state == UINPUT_RUNNING)
+ return (EINVAL);
+ ret = copyinstr(*(void **)data, buf, sizeof(buf), NULL);
+ if (ret != 0)
+ return (ret);
+ evdev_set_serial(state->ucs_evdev, buf);
+ return (0);
+
case UI_SET_SWBIT:
if (state->ucs_state == UINPUT_RUNNING ||
intdata > SW_MAX || intdata < 0)
diff --git a/freebsd/sys/dev/evdev/uinput.h b/freebsd/sys/dev/evdev/uinput.h
index dd4b0a82..d15b8945 100644
--- a/freebsd/sys/dev/evdev/uinput.h
+++ b/freebsd/sys/dev/evdev/uinput.h
@@ -90,6 +90,13 @@ struct uinput_abs_setup {
#define UI_BEGIN_FF_ERASE _IOWR(UINPUT_IOCTL_BASE, 202, struct uinput_ff_erase)
#define UI_END_FF_ERASE _IOW(UINPUT_IOCTL_BASE, 203, struct uinput_ff_erase)
+/*
+ * FreeBSD specific. Set unique identifier of input device.
+ * Name and magic are chosen to reduce chances of clashing
+ * with possible future Linux extensions.
+ */
+#define UI_SET_BSDUNIQ _IO(UINPUT_IOCTL_BASE, 109)
+
#define EV_UINPUT 0x0101
#define UI_FF_UPLOAD 1
#define UI_FF_ERASE 2
diff --git a/freebsd/sys/dev/fdt/fdt_common.c b/freebsd/sys/dev/fdt/fdt_common.c
index de4a44b9..ff32dc0a 100644
--- a/freebsd/sys/dev/fdt/fdt_common.c
+++ b/freebsd/sys/dev/fdt/fdt_common.c
@@ -61,7 +61,6 @@ __FBSDID("$FreeBSD$");
#endif
#define FDT_COMPAT_LEN 255
-#define FDT_TYPE_LEN 64
#define FDT_REG_CELLS 4
#define FDT_RANGES_SIZE 48
@@ -74,8 +73,6 @@ vm_offset_t fdt_immr_size;
struct fdt_ic_list fdt_ic_list_head = SLIST_HEAD_INITIALIZER(fdt_ic_list_head);
-static int fdt_is_compatible(phandle_t, const char *);
-
static int
fdt_get_range_by_busaddr(phandle_t node, u_long addr, u_long *base,
u_long *size)
@@ -218,7 +215,7 @@ fdt_immr_addr(vm_offset_t immr_va)
* Try to access the SOC node directly i.e. through /aliases/.
*/
if ((node = OF_finddevice("soc")) != -1)
- if (fdt_is_compatible(node, "simple-bus"))
+ if (ofw_bus_node_is_compatible(node, "simple-bus"))
goto moveon;
/*
* Find the node the long way.
@@ -239,45 +236,6 @@ moveon:
return (r);
}
-/*
- * This routine is an early-usage version of the ofw_bus_is_compatible() when
- * the ofw_bus I/F is not available (like early console routines and similar).
- * Note the buffer has to be on the stack since malloc() is usually not
- * available in such cases either.
- */
-static int
-fdt_is_compatible(phandle_t node, const char *compatstr)
-{
- char buf[FDT_COMPAT_LEN];
- char *compat;
- int len, onelen, l, rv;
-
- if ((len = OF_getproplen(node, "compatible")) <= 0)
- return (0);
-
- compat = (char *)&buf;
- bzero(compat, FDT_COMPAT_LEN);
-
- if (OF_getprop(node, "compatible", compat, FDT_COMPAT_LEN) < 0)
- return (0);
-
- onelen = strlen(compatstr);
- rv = 0;
- while (len > 0) {
- if (strncasecmp(compat, compatstr, onelen) == 0) {
- /* Found it. */
- rv = 1;
- break;
- }
- /* Slide to the next sub-string. */
- l = strlen(compat) + 1;
- compat += l;
- len -= l;
- }
-
- return (rv);
-}
-
int
fdt_is_compatible_strict(phandle_t node, const char *compatible)
{
@@ -306,7 +264,7 @@ fdt_find_compatible(phandle_t start, const char *compat, int strict)
* matching 'compatible' property.
*/
for (child = OF_child(start); child != 0; child = OF_peer(child))
- if (fdt_is_compatible(child, compat)) {
+ if (ofw_bus_node_is_compatible(child, compat)) {
if (strict)
if (!fdt_is_compatible_strict(child, compat))
continue;
@@ -325,7 +283,7 @@ fdt_depth_search_compatible(phandle_t start, const char *compat, int strict)
* matching 'compatible' property.
*/
for (node = OF_child(start); node != 0; node = OF_peer(node)) {
- if (fdt_is_compatible(node, compat) &&
+ if (ofw_bus_node_is_compatible(node, compat) &&
(strict == 0 || fdt_is_compatible_strict(node, compat))) {
return (node);
}
@@ -337,46 +295,6 @@ fdt_depth_search_compatible(phandle_t start, const char *compat, int strict)
}
int
-fdt_is_enabled(phandle_t node)
-{
- char *stat;
- int ena, len;
-
- len = OF_getprop_alloc(node, "status", sizeof(char),
- (void **)&stat);
-
- if (len <= 0)
- /* It is OK if no 'status' property. */
- return (1);
-
- /* Anything other than 'okay' means disabled. */
- ena = 0;
- if (strncmp((char *)stat, "okay", len) == 0)
- ena = 1;
-
- OF_prop_free(stat);
- return (ena);
-}
-
-int
-fdt_is_type(phandle_t node, const char *typestr)
-{
- char type[FDT_TYPE_LEN];
-
- if (OF_getproplen(node, "device_type") <= 0)
- return (0);
-
- if (OF_getprop(node, "device_type", type, FDT_TYPE_LEN) < 0)
- return (0);
-
- if (strncasecmp(type, typestr, FDT_TYPE_LEN) == 0)
- /* This fits. */
- return (1);
-
- return (0);
-}
-
-int
fdt_parent_addr_cells(phandle_t node)
{
pcell_t addr_cells;
@@ -389,19 +307,6 @@ fdt_parent_addr_cells(phandle_t node)
return ((int)fdt32_to_cpu(addr_cells));
}
-int
-fdt_pm_is_enabled(phandle_t node)
-{
- int ret;
-
- ret = 1;
-
-#if defined(SOC_MV_KIRKWOOD) || defined(SOC_MV_DISCOVERY)
- ret = fdt_pm(node);
-#endif
- return (ret);
-}
-
u_long
fdt_data_get(void *data, int cells)
{
@@ -477,59 +382,6 @@ fdt_regsize(phandle_t node, u_long *base, u_long *size)
}
int
-fdt_reg_to_rl(phandle_t node, struct resource_list *rl)
-{
- u_long end, count, start;
- pcell_t *reg, *regptr;
- pcell_t addr_cells, size_cells;
- int tuple_size, tuples;
- int i, rv;
- long busaddr, bussize;
-
- if (fdt_addrsize_cells(OF_parent(node), &addr_cells, &size_cells) != 0)
- return (ENXIO);
- if (fdt_get_range(OF_parent(node), 0, &busaddr, &bussize)) {
- busaddr = 0;
- bussize = 0;
- }
-
- tuple_size = sizeof(pcell_t) * (addr_cells + size_cells);
- tuples = OF_getprop_alloc(node, "reg", tuple_size, (void **)&reg);
- debugf("addr_cells = %d, size_cells = %d\n", addr_cells, size_cells);
- debugf("tuples = %d, tuple size = %d\n", tuples, tuple_size);
- if (tuples <= 0)
- /* No 'reg' property in this node. */
- return (0);
-
- regptr = reg;
- for (i = 0; i < tuples; i++) {
-
- rv = fdt_data_to_res(reg, addr_cells, size_cells, &start,
- &count);
- if (rv != 0) {
- resource_list_free(rl);
- goto out;
- }
- reg += addr_cells + size_cells;
-
- /* Calculate address range relative to base. */
- start += busaddr;
- end = start + count - 1;
-
- debugf("reg addr start = %lx, end = %lx, count = %lx\n", start,
- end, count);
-
- resource_list_add(rl, SYS_RES_MEMORY, i, start, end,
- count);
- }
- rv = 0;
-
-out:
- OF_prop_free(regptr);
- return (rv);
-}
-
-int
fdt_get_phyaddr(phandle_t node, device_t dev, int *phy_addr, void **phy_sc)
{
phandle_t phy_node;
@@ -650,6 +502,47 @@ out:
}
int
+fdt_get_reserved_mem(struct mem_region *reserved, int *mreserved)
+{
+ pcell_t reg[FDT_REG_CELLS];
+ phandle_t child, root;
+ int addr_cells, size_cells;
+ int i, rv;
+
+ root = OF_finddevice("/reserved-memory");
+ if (root == -1) {
+ return (ENXIO);
+ }
+
+ if ((rv = fdt_addrsize_cells(root, &addr_cells, &size_cells)) != 0)
+ return (rv);
+
+ if (addr_cells + size_cells > FDT_REG_CELLS)
+ panic("Too many address and size cells %d %d", addr_cells,
+ size_cells);
+
+ i = 0;
+ for (child = OF_child(root); child != 0; child = OF_peer(child)) {
+ if (!OF_hasprop(child, "no-map"))
+ continue;
+
+ rv = OF_getprop(child, "reg", reg, sizeof(reg));
+ if (rv <= 0)
+ /* XXX: Does a no-map of a dynamic range make sense? */
+ continue;
+
+ fdt_data_to_res(reg, addr_cells, size_cells,
+ (u_long *)&reserved[i].mr_start,
+ (u_long *)&reserved[i].mr_size);
+ i++;
+ }
+
+ *mreserved = i;
+
+ return (0);
+}
+
+int
fdt_get_mem_regions(struct mem_region *mr, int *mrcnt, uint64_t *memsize)
{
pcell_t reg[FDT_REG_CELLS * FDT_MEM_REGIONS];
@@ -715,17 +608,6 @@ out:
}
int
-fdt_get_unit(device_t dev)
-{
- const char * name;
-
- name = ofw_bus_get_name(dev);
- name = strchr(name, '@') + 1;
-
- return (strtol(name,NULL,0));
-}
-
-int
fdt_get_chosen_bootargs(char *bootargs, size_t max_size)
{
phandle_t chosen;
diff --git a/freebsd/sys/dev/fdt/fdt_common.h b/freebsd/sys/dev/fdt/fdt_common.h
index 91522df5..3bf4df41 100644
--- a/freebsd/sys/dev/fdt/fdt_common.h
+++ b/freebsd/sys/dev/fdt/fdt_common.h
@@ -39,7 +39,7 @@
#include <contrib/libfdt/libfdt_env.h>
#include <dev/ofw/ofw_bus.h>
-#define FDT_MEM_REGIONS 8
+#define FDT_MEM_REGIONS 16
#define DI_MAX_INTR_NUM 32
@@ -85,19 +85,14 @@ int fdt_data_to_res(pcell_t *, int, int, u_long *, u_long *);
phandle_t fdt_find_compatible(phandle_t, const char *, int);
phandle_t fdt_depth_search_compatible(phandle_t, const char *, int);
int fdt_get_mem_regions(struct mem_region *, int *, uint64_t *);
+int fdt_get_reserved_mem(struct mem_region *, int *);
int fdt_get_reserved_regions(struct mem_region *, int *);
int fdt_get_phyaddr(phandle_t, device_t, int *, void **);
int fdt_get_range(phandle_t, int, u_long *, u_long *);
int fdt_immr_addr(vm_offset_t);
int fdt_regsize(phandle_t, u_long *, u_long *);
int fdt_is_compatible_strict(phandle_t, const char *);
-int fdt_is_enabled(phandle_t);
-int fdt_pm_is_enabled(phandle_t);
-int fdt_is_type(phandle_t, const char *);
int fdt_parent_addr_cells(phandle_t);
-int fdt_reg_to_rl(phandle_t, struct resource_list *);
-int fdt_pm(phandle_t);
-int fdt_get_unit(device_t);
int fdt_get_chosen_bootargs(char *bootargs, size_t max_size);
#endif /* _FDT_COMMON_H_ */
diff --git a/freebsd/sys/dev/ffec/if_ffec.c b/freebsd/sys/dev/ffec/if_ffec.c
index 1d842286..03dca1a9 100644
--- a/freebsd/sys/dev/ffec/if_ffec.c
+++ b/freebsd/sys/dev/ffec/if_ffec.c
@@ -1093,7 +1093,7 @@ ffec_setup_rxfilter(struct ffec_softc *sc)
else {
ghash = 0;
if_maddr_rlock(ifp);
- TAILQ_FOREACH(ifma, &sc->ifp->if_multiaddrs, ifma_link) {
+ CK_STAILQ_FOREACH(ifma, &sc->ifp->if_multiaddrs, ifma_link) {
if (ifma->ifma_addr->sa_family != AF_LINK)
continue;
/* 6 bits from MSB in LE CRC32 are used for hash. */
diff --git a/freebsd/sys/dev/gpio/ofw_gpiobus.c b/freebsd/sys/dev/gpio/ofw_gpiobus.c
index 1a87121c..ac0ea9bf 100644
--- a/freebsd/sys/dev/gpio/ofw_gpiobus.c
+++ b/freebsd/sys/dev/gpio/ofw_gpiobus.c
@@ -370,7 +370,7 @@ ofw_gpiobus_parse_gpios_impl(device_t consumer, phandle_t cnode, char *pname,
pcell_t *gpios;
phandle_t gpio;
- ncells = OF_getencprop_alloc(cnode, pname, sizeof(*gpios),
+ ncells = OF_getencprop_alloc_multi(cnode, pname, sizeof(*gpios),
(void **)&gpios);
if (ncells == -1) {
device_printf(consumer,
diff --git a/freebsd/sys/dev/mmc/mmcreg.h b/freebsd/sys/dev/mmc/mmcreg.h
index 5f58ce3f..4b1f8a0e 100644
--- a/freebsd/sys/dev/mmc/mmcreg.h
+++ b/freebsd/sys/dev/mmc/mmcreg.h
@@ -162,34 +162,35 @@ struct mmc_command {
#define R1_STATE_PRG 7
#define R1_STATE_DIS 8
-/* R4 response (SDIO) */
-#define R4_IO_NUM_FUNCTIONS(ocr) (((ocr) >> 28) & 0x3)
-#define R4_IO_MEM_PRESENT (0x1<<27)
-#define R4_IO_OCR_MASK 0x00fffff0
+/* R4 responses (SDIO) */
+#define R4_IO_NUM_FUNCTIONS(ocr) (((ocr) >> 28) & 0x3)
+#define R4_IO_MEM_PRESENT (0x1 << 27)
+#define R4_IO_OCR_MASK 0x00fffff0
/*
* R5 responses
*
* Types (per SD 2.0 standard)
- *e : error bit
- *s : status bit
- *r : detected and set for the actual command response
- *x : Detected and set during command execution. The host can get
- * the status by issuing a command with R1 response.
+ * e : error bit
+ * s : status bit
+ * r : detected and set for the actual command response
+ * x : Detected and set during command execution. The host can get
+ * the status by issuing a command with R1 response.
*
* Clear Condition (per SD 2.0 standard)
- *a : according to the card current state.
- *b : always related to the previous command. reception of a valid
- * command will clear it (with a delay of one command).
- *c : clear by read
+ * a : according to the card current state.
+ * b : always related to the previous command. reception of a valid
+ * command will clear it (with a delay of one command).
+ * c : clear by read
*/
-#define R5_COM_CRC_ERROR (1u << 15)/* er, b */
-#define R5_ILLEGAL_COMMAND (1u << 14)/* er, b */
-#define R5_IO_CURRENT_STATE_MASK (3u << 12)/* s, b */
-#define R5_IO_CURRENT_STATE(x) (((x) & R5_IO_CURRENT_STATE_MASK) >> 12)
-#define R5_ERROR (1u << 11)/* erx, c */
-#define R5_FUNCTION_NUMBER (1u << 9)/* er, c */
-#define R5_OUT_OF_RANGE (1u << 8)/* er, c */
+#define R5_COM_CRC_ERROR (1u << 15) /* er, b */
+#define R5_ILLEGAL_COMMAND (1u << 14) /* er, b */
+#define R5_IO_CURRENT_STATE_MASK (3u << 12) /* s, b */
+#define R5_IO_CURRENT_STATE(x) (((x) & R5_IO_CURRENT_STATE_MASK) >> 12)
+#define R5_ERROR (1u << 11) /* erx, c */
+#define R5_FUNCTION_NUMBER (1u << 9) /* er, c */
+#define R5_OUT_OF_RANGE (1u << 8) /* er, c */
+
struct mmc_data {
size_t len; /* size of the data */
size_t xfer_len;
@@ -227,7 +228,7 @@ struct mmc_request {
#define SD_SEND_RELATIVE_ADDR 3
#define MMC_SET_DSR 4
#define MMC_SLEEP_AWAKE 5
-#define IO_SEND_OP_COND 5
+#define IO_SEND_OP_COND 5
#define MMC_SWITCH_FUNC 6
#define MMC_SWITCH_FUNC_CMDS 0
#define MMC_SWITCH_FUNC_SET 1
@@ -318,30 +319,30 @@ struct mmc_request {
/* Class 9: I/O cards (sd) */
#define SD_IO_RW_DIRECT 52
/* CMD52 arguments */
-#define SD_ARG_CMD52_READ (0<<31)
-#define SD_ARG_CMD52_WRITE (1<<31)
-#define SD_ARG_CMD52_FUNC_SHIFT 28
-#define SD_ARG_CMD52_FUNC_MASK 0x7
-#define SD_ARG_CMD52_EXCHANGE (1<<27)
-#define SD_ARG_CMD52_REG_SHIFT 9
-#define SD_ARG_CMD52_REG_MASK 0x1ffff
-#define SD_ARG_CMD52_DATA_SHIFT 0
-#define SD_ARG_CMD52_DATA_MASK 0xff
-#define SD_R5_DATA(resp) ((resp)[0] & 0xff)
+#define SD_ARG_CMD52_READ (0 << 31)
+#define SD_ARG_CMD52_WRITE (1 << 31)
+#define SD_ARG_CMD52_FUNC_SHIFT 28
+#define SD_ARG_CMD52_FUNC_MASK 0x7
+#define SD_ARG_CMD52_EXCHANGE (1 << 27)
+#define SD_ARG_CMD52_REG_SHIFT 9
+#define SD_ARG_CMD52_REG_MASK 0x1ffff
+#define SD_ARG_CMD52_DATA_SHIFT 0
+#define SD_ARG_CMD52_DATA_MASK 0xff
+#define SD_R5_DATA(resp) ((resp)[0] & 0xff)
#define SD_IO_RW_EXTENDED 53
/* CMD53 arguments */
-#define SD_ARG_CMD53_READ (0<<31)
-#define SD_ARG_CMD53_WRITE (1<<31)
-#define SD_ARG_CMD53_FUNC_SHIFT 28
-#define SD_ARG_CMD53_FUNC_MASK 0x7
-#define SD_ARG_CMD53_BLOCK_MODE (1<<27)
-#define SD_ARG_CMD53_INCREMENT (1<<26)
-#define SD_ARG_CMD53_REG_SHIFT 9
-#define SD_ARG_CMD53_REG_MASK 0x1ffff
-#define SD_ARG_CMD53_LENGTH_SHIFT 0
-#define SD_ARG_CMD53_LENGTH_MASK 0x1ff
-#define SD_ARG_CMD53_LENGTH_MAX 64 /* XXX should be 511? */
+#define SD_ARG_CMD53_READ (0 << 31)
+#define SD_ARG_CMD53_WRITE (1 << 31)
+#define SD_ARG_CMD53_FUNC_SHIFT 28
+#define SD_ARG_CMD53_FUNC_MASK 0x7
+#define SD_ARG_CMD53_BLOCK_MODE (1 << 27)
+#define SD_ARG_CMD53_INCREMENT (1 << 26)
+#define SD_ARG_CMD53_REG_SHIFT 9
+#define SD_ARG_CMD53_REG_MASK 0x1ffff
+#define SD_ARG_CMD53_LENGTH_SHIFT 0
+#define SD_ARG_CMD53_LENGTH_MASK 0x1ff
+#define SD_ARG_CMD53_LENGTH_MAX 64 /* XXX should be 511? */
/* Class 10: Switch function commands */
#define SD_SWITCH_FUNC 6
@@ -364,6 +365,8 @@ struct mmc_request {
/*
* EXT_CSD fields
*/
+#define EXT_CSD_FLUSH_CACHE 32 /* W/E */
+#define EXT_CSD_CACHE_CTRL 33 /* R/W/E */
#define EXT_CSD_EXT_PART_ATTR 52 /* R/W, 2 bytes */
#define EXT_CSD_ENH_START_ADDR 136 /* R/W, 4 bytes */
#define EXT_CSD_ENH_SIZE_MULT 140 /* R/W, 3 bytes */
@@ -397,12 +400,19 @@ struct mmc_request {
#define EXT_CSD_PWR_CL_200_360 237 /* RO */
#define EXT_CSD_PWR_CL_52_195_DDR 238 /* RO */
#define EXT_CSD_PWR_CL_52_360_DDR 239 /* RO */
+#define EXT_CSD_CACHE_FLUSH_POLICY 249 /* RO */
#define EXT_CSD_GEN_CMD6_TIME 248 /* RO */
+#define EXT_CSD_CACHE_SIZE 249 /* RO, 4 bytes */
#define EXT_CSD_PWR_CL_200_360_DDR 253 /* RO */
/*
* EXT_CSD field definitions
*/
+#define EXT_CSD_FLUSH_CACHE_FLUSH 0x01
+#define EXT_CSD_FLUSH_CACHE_BARRIER 0x02
+
+#define EXT_CSD_CACHE_CTRL_CACHE_EN 0x01
+
#define EXT_CSD_EXT_PART_ATTR_DEFAULT 0x0
#define EXT_CSD_EXT_PART_ATTR_SYSTEMCODE 0x1
#define EXT_CSD_EXT_PART_ATTR_NPERSISTENT 0x2
@@ -482,6 +492,8 @@ struct mmc_request {
#define EXT_CSD_SEC_FEATURE_SUPPORT_GB_CL_EN 0x10
#define EXT_CSD_SEC_FEATURE_SUPPORT_SANITIZE 0x40
+#define EXT_CSD_CACHE_FLUSH_POLICY_FIFO 0x01
+
/*
* Vendor specific EXT_CSD fields
*/
@@ -533,50 +545,50 @@ struct mmc_request {
/*
* SDIO Direct & Extended I/O
*/
-#define SD_IO_RW_WR (1u << 31)
-#define SD_IO_RW_FUNC(x) (((x) & 0x7) << 28)
-#define SD_IO_RW_RAW (1u << 27)
-#define SD_IO_RW_INCR (1u << 26)
-#define SD_IO_RW_ADR(x) (((x) & 0x1FFFF) << 9)
-#define SD_IO_RW_DAT(x) (((x) & 0xFF) << 0)
-#define SD_IO_RW_LEN(x) (((x) & 0xFF) << 0)
+#define SD_IO_RW_WR (1u << 31)
+#define SD_IO_RW_FUNC(x) (((x) & 0x7) << 28)
+#define SD_IO_RW_RAW (1u << 27)
+#define SD_IO_RW_INCR (1u << 26)
+#define SD_IO_RW_ADR(x) (((x) & 0x1FFFF) << 9)
+#define SD_IO_RW_DAT(x) (((x) & 0xFF) << 0)
+#define SD_IO_RW_LEN(x) (((x) & 0xFF) << 0)
-#define SD_IOE_RW_LEN(x) (((x) & 0x1FF) << 0)
-#define SD_IOE_RW_BLK (1u << 27)
+#define SD_IOE_RW_LEN(x) (((x) & 0x1FF) << 0)
+#define SD_IOE_RW_BLK (1u << 27)
/* Card Common Control Registers (CCCR) */
-#define SD_IO_CCCR_START 0x00000
-#define SD_IO_CCCR_SIZE 0x100
-#define SD_IO_CCCR_FN_ENABLE 0x02
-#define SD_IO_CCCR_FN_READY 0x03
-#define SD_IO_CCCR_INT_ENABLE 0x04
-#define SD_IO_CCCR_INT_PENDING 0x05
-#define SD_IO_CCCR_CTL 0x06
-#define CCCR_CTL_RES (1<<3)
-#define SD_IO_CCCR_BUS_WIDTH 0x07
-#define CCCR_BUS_WIDTH_4 (1<<1)
-#define CCCR_BUS_WIDTH_1 (1<<0)
-#define SD_IO_CCCR_CARDCAP 0x08
-#define SD_IO_CCCR_CISPTR 0x09 /* XXX 9-10, 10-11, or 9-12 */
+#define SD_IO_CCCR_START 0x00000
+#define SD_IO_CCCR_SIZE 0x100
+#define SD_IO_CCCR_FN_ENABLE 0x02
+#define SD_IO_CCCR_FN_READY 0x03
+#define SD_IO_CCCR_INT_ENABLE 0x04
+#define SD_IO_CCCR_INT_PENDING 0x05
+#define SD_IO_CCCR_CTL 0x06
+#define CCCR_CTL_RES (1 << 3)
+#define SD_IO_CCCR_BUS_WIDTH 0x07
+#define CCCR_BUS_WIDTH_4 (1 << 1)
+#define CCCR_BUS_WIDTH_1 (1 << 0)
+#define SD_IO_CCCR_CARDCAP 0x08
+#define SD_IO_CCCR_CISPTR 0x09 /* XXX 9-10, 10-11, or 9-12 */
/* Function Basic Registers (FBR) */
-#define SD_IO_FBR_START 0x00100
-#define SD_IO_FBR_SIZE 0x00700
+#define SD_IO_FBR_START 0x00100
+#define SD_IO_FBR_SIZE 0x00700
/* Card Information Structure (CIS) */
-#define SD_IO_CIS_START 0x01000
-#define SD_IO_CIS_SIZE 0x17000
+#define SD_IO_CIS_START 0x01000
+#define SD_IO_CIS_SIZE 0x17000
/* CIS tuple codes (based on PC Card 16) */
-#define SD_IO_CISTPL_VERS_1 0x15
-#define SD_IO_CISTPL_MANFID 0x20
-#define SD_IO_CISTPL_FUNCID 0x21
-#define SD_IO_CISTPL_FUNCE 0x22
-#define SD_IO_CISTPL_END 0xff
+#define SD_IO_CISTPL_VERS_1 0x15
+#define SD_IO_CISTPL_MANFID 0x20
+#define SD_IO_CISTPL_FUNCID 0x21
+#define SD_IO_CISTPL_FUNCE 0x22
+#define SD_IO_CISTPL_END 0xff
/* CISTPL_FUNCID codes */
/* OpenBSD incorrectly defines 0x0c as FUNCTION_WLAN */
-/* #define SDMMC_FUNCTION_WLAN 0x0c */
+/* #define SDMMC_FUNCTION_WLAN 0x0c */
/* OCR bits */
diff --git a/freebsd/sys/dev/mmc/mmcsd.c b/freebsd/sys/dev/mmc/mmcsd.c
index 94e6e73f..263da55d 100644
--- a/freebsd/sys/dev/mmc/mmcsd.c
+++ b/freebsd/sys/dev/mmc/mmcsd.c
@@ -71,7 +71,9 @@ __FBSDID("$FreeBSD$");
#include <sys/malloc.h>
#include <sys/module.h>
#include <sys/mutex.h>
+#include <sys/priv.h>
#include <sys/slicer.h>
+#include <sys/sysctl.h>
#include <sys/time.h>
#include <geom/geom.h>
@@ -142,6 +144,8 @@ struct mmcsd_softc {
uint32_t flags;
#define MMCSD_INAND_CMD38 0x0001
#define MMCSD_USE_TRIM 0x0002
+#define MMCSD_FLUSH_CACHE 0x0004
+#define MMCSD_DIRTY 0x0008
uint32_t cmd6_time; /* Generic switch timeout [us] */
uint32_t part_time; /* Partition switch timeout [us] */
off_t enh_base; /* Enhanced user data area slice base ... */
@@ -166,12 +170,19 @@ static const char * const errmsg[] =
"NO MEMORY"
};
+static SYSCTL_NODE(_hw, OID_AUTO, mmcsd, CTLFLAG_RD, NULL, "mmcsd driver");
+
+static int mmcsd_cache = 1;
+SYSCTL_INT(_hw_mmcsd, OID_AUTO, cache, CTLFLAG_RDTUN, &mmcsd_cache, 0,
+ "Device R/W cache enabled if present");
+
#define LOG_PPS 5 /* Log no more than 5 errors per second. */
/* bus entry points */
static int mmcsd_attach(device_t dev);
static int mmcsd_detach(device_t dev);
static int mmcsd_probe(device_t dev);
+static int mmcsd_shutdown(device_t dev);
#ifndef __rtems__
/* disk routines */
@@ -181,7 +192,6 @@ static int mmcsd_dump(void *arg, void *virtual, vm_offset_t physical,
static int mmcsd_getattr(struct bio *);
static int mmcsd_ioctl_disk(struct disk *disk, u_long cmd, void *data,
int fflag, struct thread *td);
-static int mmcsd_open(struct disk *dp);
static void mmcsd_strategy(struct bio *bp);
static void mmcsd_task(void *arg);
#endif /* __rtems__ */
@@ -197,8 +207,12 @@ static int mmcsd_bus_bit_width(device_t dev);
static daddr_t mmcsd_delete(struct mmcsd_part *part, struct bio *bp);
#endif /* __rtems__ */
static const char *mmcsd_errmsg(int e);
+#ifndef __rtems__
+static int mmcsd_flush_cache(struct mmcsd_softc *sc);
+#endif /* __rtems__ */
+static const char *mmcsd_errmsg(int e);
static int mmcsd_ioctl(struct mmcsd_part *part, u_long cmd, void *data,
- int fflag);
+ int fflag, struct thread *td);
static int mmcsd_ioctl_cmd(struct mmcsd_part *part, struct mmc_ioc_cmd *mic,
int fflag);
static uintmax_t mmcsd_pretty_size(off_t size, char *unit);
@@ -523,6 +537,31 @@ mmcsd_attach(device_t dev)
rev = ext_csd[EXT_CSD_REV];
/*
+ * With revision 1.5 (MMC v4.5, EXT_CSD_REV == 6) and later, take
+ * advantage of the device R/W cache if present and useage is not
+ * disabled.
+ */
+ if (rev >= 6 && mmcsd_cache != 0) {
+ size = ext_csd[EXT_CSD_CACHE_SIZE] |
+ ext_csd[EXT_CSD_CACHE_SIZE + 1] << 8 |
+ ext_csd[EXT_CSD_CACHE_SIZE + 2] << 16 |
+ ext_csd[EXT_CSD_CACHE_SIZE + 3] << 24;
+ if (bootverbose)
+ device_printf(dev, "cache size %juKB\n", size);
+ if (size > 0) {
+ MMCBUS_ACQUIRE_BUS(mmcbus, dev);
+ err = mmc_switch(mmcbus, dev, sc->rca,
+ EXT_CSD_CMD_SET_NORMAL, EXT_CSD_CACHE_CTRL,
+ EXT_CSD_CACHE_CTRL_CACHE_EN, sc->cmd6_time, true);
+ MMCBUS_RELEASE_BUS(mmcbus, dev);
+ if (err != MMC_ERR_NONE)
+ device_printf(dev, "failed to enable cache\n");
+ else
+ sc->flags |= MMCSD_FLUSH_CACHE;
+ }
+ }
+
+ /*
* Ignore user-creatable enhanced user data area and general purpose
* partitions partitions as long as partitioning hasn't been finished.
*/
@@ -734,7 +773,6 @@ mmcsd_add_part(struct mmcsd_softc *sc, u_int type, const char *name, u_int cnt,
#ifndef __rtems__
d = part->disk = disk_alloc();
- d->d_open = mmcsd_open;
d->d_close = mmcsd_close;
d->d_strategy = mmcsd_strategy;
d->d_ioctl = mmcsd_ioctl_disk;
@@ -748,6 +786,8 @@ mmcsd_add_part(struct mmcsd_softc *sc, u_int type, const char *name, u_int cnt,
d->d_stripesize = sc->erase_sector * d->d_sectorsize;
d->d_unit = cnt;
d->d_flags = DISKFLAG_CANDELETE;
+ if ((sc->flags & MMCSD_FLUSH_CACHE) != 0)
+ d->d_flags |= DISKFLAG_CANFLUSHCACHE;
d->d_delmaxsize = mmc_get_erase_sector(dev) * d->d_sectorsize;
strlcpy(d->d_ident, mmc_get_card_sn_string(dev),
sizeof(d->d_ident));
@@ -908,6 +948,22 @@ mmcsd_detach(device_t dev)
free(part, M_DEVBUF);
}
}
+ if (mmcsd_flush_cache(sc) != MMC_ERR_NONE)
+ device_printf(dev, "failed to flush cache\n");
+#else /* __rtems__ */
+ BSD_PANIC("FIXME");
+#endif /* __rtems__ */
+ return (0);
+}
+
+static int
+mmcsd_shutdown(device_t dev)
+{
+#ifndef __rtems__
+ struct mmcsd_softc *sc = device_get_softc(dev);
+
+ if (mmcsd_flush_cache(sc) != MMC_ERR_NONE)
+ device_printf(dev, "failed to flush cache\n");
#else /* __rtems__ */
BSD_PANIC("FIXME");
#endif /* __rtems__ */
@@ -947,6 +1003,8 @@ mmcsd_suspend(device_t dev)
MMCSD_IOCTL_UNLOCK(part);
}
}
+ if (mmcsd_flush_cache(sc) != MMC_ERR_NONE)
+ device_printf(dev, "failed to flush cache\n");
#else /* __rtems__ */
BSD_PANIC("FIXME");
#endif /* __rtems__ */
@@ -989,16 +1047,15 @@ mmcsd_resume(device_t dev)
#ifndef __rtems__
static int
-mmcsd_open(struct disk *dp __unused)
-{
-
- return (0);
-}
-
-static int
-mmcsd_close(struct disk *dp __unused)
+mmcsd_close(struct disk *dp)
{
+ struct mmcsd_softc *sc;
+ if ((dp->d_flags & DISKFLAG_OPEN) != 0) {
+ sc = ((struct mmcsd_part *)dp->d_drv1)->sc;
+ if (mmcsd_flush_cache(sc) != MMC_ERR_NONE)
+ device_printf(sc->dev, "failed to flush cache\n");
+ }
return (0);
}
@@ -1022,24 +1079,25 @@ mmcsd_strategy(struct bio *bp)
static int
mmcsd_ioctl_rpmb(struct cdev *dev, u_long cmd, caddr_t data,
- int fflag, struct thread *td __unused)
+ int fflag, struct thread *td)
{
- return (mmcsd_ioctl(dev->si_drv1, cmd, data, fflag));
+ return (mmcsd_ioctl(dev->si_drv1, cmd, data, fflag, td));
}
#ifndef __rtems__
static int
mmcsd_ioctl_disk(struct disk *disk, u_long cmd, void *data, int fflag,
- struct thread *td __unused)
+ struct thread *td)
{
- return (mmcsd_ioctl(disk->d_drv1, cmd, data, fflag));
+ return (mmcsd_ioctl(disk->d_drv1, cmd, data, fflag, td));
}
#endif /* __rtems__ */
static int
-mmcsd_ioctl(struct mmcsd_part *part, u_long cmd, void *data, int fflag)
+mmcsd_ioctl(struct mmcsd_part *part, u_long cmd, void *data, int fflag,
+ struct thread *td)
{
struct mmc_ioc_cmd *mic;
struct mmc_ioc_multi_cmd *mimc;
@@ -1049,6 +1107,10 @@ mmcsd_ioctl(struct mmcsd_part *part, u_long cmd, void *data, int fflag)
if ((fflag & FREAD) == 0)
return (EBADF);
+ err = priv_check(td, PRIV_DRIVER);
+ if (err != 0)
+ return (err);
+
err = 0;
switch (cmd) {
case MMC_IOC_CMD:
@@ -1190,6 +1252,8 @@ mmcsd_ioctl_cmd(struct mmcsd_part *part, struct mmc_ioc_cmd *mic, int fflag)
if (err != MMC_ERR_NONE)
goto switch_back;
}
+ if (mic->write_flag != 0)
+ sc->flags |= MMCSD_DIRTY;
if (mic->is_acmd != 0)
(void)mmc_wait_for_app_cmd(mmcbus, dev, rca, &cmd, 0);
else
@@ -1405,6 +1469,7 @@ mmcsd_rw(struct mmcsd_part *part, struct bio *bp)
else
cmd.opcode = MMC_READ_SINGLE_BLOCK;
} else {
+ sc->flags |= MMCSD_DIRTY;
if (numblocks > 1)
cmd.opcode = MMC_WRITE_MULTIPLE_BLOCK;
else
@@ -1590,13 +1655,18 @@ mmcsd_dump(void *arg, void *virtual, vm_offset_t physical, off_t offset,
device_t dev, mmcbus;
int err;
- /* length zero is special and really means flush buffers to media */
- if (!length)
- return (0);
-
disk = arg;
part = disk->d_drv1;
sc = part->sc;
+
+ /* length zero is special and really means flush buffers to media */
+ if (length == 0) {
+ err = mmcsd_flush_cache(sc);
+ if (err != MMC_ERR_NONE)
+ return (EIO);
+ return (0);
+ }
+
dev = sc->dev;
mmcbus = sc->mmcbus;
@@ -1646,6 +1716,14 @@ mmcsd_task(void *arg)
"mmcsd disk jobqueue", 0);
} while (bp == NULL);
MMCSD_DISK_UNLOCK(part);
+ if (__predict_false(bp->bio_cmd == BIO_FLUSH)) {
+ if (mmcsd_flush_cache(sc) != MMC_ERR_NONE) {
+ bp->bio_error = EIO;
+ bp->bio_flags |= BIO_ERROR;
+ }
+ biodone(bp);
+ continue;
+ }
if (bp->bio_cmd != BIO_READ && part->ro) {
bp->bio_error = EROFS;
bp->bio_resid = bp->bio_bcount;
@@ -1704,10 +1782,37 @@ mmcsd_bus_bit_width(device_t dev)
return (8);
}
+#ifndef __rtems__
+static int
+mmcsd_flush_cache(struct mmcsd_softc *sc)
+{
+ device_t dev, mmcbus;
+ int err;
+
+ if ((sc->flags & MMCSD_FLUSH_CACHE) == 0)
+ return (MMC_ERR_NONE);
+
+ dev = sc->dev;
+ mmcbus = sc->mmcbus;
+ MMCBUS_ACQUIRE_BUS(mmcbus, dev);
+ if ((sc->flags & MMCSD_DIRTY) == 0) {
+ MMCBUS_RELEASE_BUS(mmcbus, dev);
+ return (MMC_ERR_NONE);
+ }
+ err = mmc_switch(mmcbus, dev, sc->rca, EXT_CSD_CMD_SET_NORMAL,
+ EXT_CSD_FLUSH_CACHE, EXT_CSD_FLUSH_CACHE_FLUSH, 60 * 1000, true);
+ if (err == MMC_ERR_NONE)
+ sc->flags &= ~MMCSD_DIRTY;
+ MMCBUS_RELEASE_BUS(mmcbus, dev);
+ return (err);
+}
+#endif /* __rtems__ */
+
static device_method_t mmcsd_methods[] = {
DEVMETHOD(device_probe, mmcsd_probe),
DEVMETHOD(device_attach, mmcsd_attach),
DEVMETHOD(device_detach, mmcsd_detach),
+ DEVMETHOD(device_shutdown, mmcsd_shutdown),
DEVMETHOD(device_suspend, mmcsd_suspend),
DEVMETHOD(device_resume, mmcsd_resume),
DEVMETHOD_END
diff --git a/freebsd/sys/dev/nvme/nvme.h b/freebsd/sys/dev/nvme/nvme.h
index b51b4a97..169f22d1 100644
--- a/freebsd/sys/dev/nvme/nvme.h
+++ b/freebsd/sys/dev/nvme/nvme.h
@@ -115,7 +115,7 @@
#define NVME_CMD_FUSE_SHIFT (8)
#define NVME_CMD_FUSE_MASK (0x3)
-#define NVME_CMD_SET_OPC(opc) (htole16(((opc) & NVME_CMD_OPC_MASK) << NVME_CMD_OPC_SHIFT))
+#define NVME_CMD_SET_OPC(opc) (htole16(((uint16_t)(opc) & NVME_CMD_OPC_MASK) << NVME_CMD_OPC_SHIFT))
#define NVME_STATUS_P_SHIFT (0)
#define NVME_STATUS_P_MASK (0x1)
@@ -1091,6 +1091,12 @@ struct nvme_firmware_page {
_Static_assert(sizeof(struct nvme_firmware_page) == 512, "bad size for nvme_firmware_page");
+struct nvme_ns_list {
+ uint32_t ns[1024];
+} __packed __aligned(4);
+
+_Static_assert(sizeof(struct nvme_ns_list) == 4096, "bad size for nvme_ns_list");
+
struct intel_log_temp_stats
{
uint64_t current;
@@ -1470,6 +1476,15 @@ void nvme_firmware_page_swapbytes(struct nvme_firmware_page *s)
}
static inline
+void nvme_ns_list_swapbytes(struct nvme_ns_list *s)
+{
+ int i;
+
+ for (i = 0; i < 1024; i++)
+ s->ns[i] = le32toh(s->ns[i]);
+}
+
+static inline
void intel_log_temp_stats_swapbytes(struct intel_log_temp_stats *s)
{
diff --git a/freebsd/sys/dev/ofw/ofw_bus_subr.c b/freebsd/sys/dev/ofw/ofw_bus_subr.c
index 8406988f..5038bb03 100644
--- a/freebsd/sys/dev/ofw/ofw_bus_subr.c
+++ b/freebsd/sys/dev/ofw/ofw_bus_subr.c
@@ -59,12 +59,12 @@ ofw_bus_gen_setup_devinfo(struct ofw_bus_devinfo *obd, phandle_t node)
if (obd == NULL)
return (ENOMEM);
/* The 'name' property is considered mandatory. */
- if ((OF_getprop_alloc(node, "name", 1, (void **)&obd->obd_name)) == -1)
+ if ((OF_getprop_alloc(node, "name", (void **)&obd->obd_name)) == -1)
return (EINVAL);
- OF_getprop_alloc(node, "compatible", 1, (void **)&obd->obd_compat);
- OF_getprop_alloc(node, "device_type", 1, (void **)&obd->obd_type);
- OF_getprop_alloc(node, "model", 1, (void **)&obd->obd_model);
- OF_getprop_alloc(node, "status", 1, (void **)&obd->obd_status);
+ OF_getprop_alloc(node, "compatible", (void **)&obd->obd_compat);
+ OF_getprop_alloc(node, "device_type", (void **)&obd->obd_type);
+ OF_getprop_alloc(node, "model", (void **)&obd->obd_model);
+ OF_getprop_alloc(node, "status", (void **)&obd->obd_status);
obd->obd_node = node;
return (0);
}
@@ -321,10 +321,10 @@ ofw_bus_setup_iinfo(phandle_t node, struct ofw_bus_iinfo *ii, int intrsz)
addrc = 2;
ii->opi_addrc = addrc * sizeof(pcell_t);
- ii->opi_imapsz = OF_getencprop_alloc(node, "interrupt-map", 1,
+ ii->opi_imapsz = OF_getencprop_alloc(node, "interrupt-map",
(void **)&ii->opi_imap);
if (ii->opi_imapsz > 0) {
- msksz = OF_getencprop_alloc(node, "interrupt-map-mask", 1,
+ msksz = OF_getencprop_alloc(node, "interrupt-map-mask",
(void **)&ii->opi_imapmsk);
/*
* Failure to get the mask is ignored; a full mask is used
@@ -451,7 +451,8 @@ ofw_bus_msimap(phandle_t node, uint16_t pci_rid, phandle_t *msi_parent,
int err, i;
/* TODO: This should be OF_searchprop_alloc if we had it */
- len = OF_getencprop_alloc(node, "msi-map", sizeof(*map), (void **)&map);
+ len = OF_getencprop_alloc_multi(node, "msi-map", sizeof(*map),
+ (void **)&map);
if (len < 0) {
if (msi_parent != NULL) {
*msi_parent = 0;
@@ -491,9 +492,9 @@ ofw_bus_msimap(phandle_t node, uint16_t pci_rid, phandle_t *msi_parent,
return (err);
}
-int
-ofw_bus_reg_to_rl(device_t dev, phandle_t node, pcell_t acells, pcell_t scells,
- struct resource_list *rl)
+static int
+ofw_bus_reg_to_rl_helper(device_t dev, phandle_t node, pcell_t acells, pcell_t scells,
+ struct resource_list *rl, const char *reg_source)
{
uint64_t phys, size;
ssize_t i, j, rid, nreg, ret;
@@ -504,11 +505,12 @@ ofw_bus_reg_to_rl(device_t dev, phandle_t node, pcell_t acells, pcell_t scells,
* This may be just redundant when having ofw_bus_devinfo
* but makes this routine independent of it.
*/
- ret = OF_getprop_alloc(node, "name", sizeof(*name), (void **)&name);
+ ret = OF_getprop_alloc(node, "name", (void **)&name);
if (ret == -1)
name = NULL;
- ret = OF_getencprop_alloc(node, "reg", sizeof(*reg), (void **)&reg);
+ ret = OF_getencprop_alloc_multi(node, reg_source, sizeof(*reg),
+ (void **)&reg);
nreg = (ret == -1) ? 0 : ret;
if (nreg % (acells + scells) != 0) {
@@ -539,6 +541,23 @@ ofw_bus_reg_to_rl(device_t dev, phandle_t node, pcell_t acells, pcell_t scells,
return (0);
}
+int
+ofw_bus_reg_to_rl(device_t dev, phandle_t node, pcell_t acells, pcell_t scells,
+ struct resource_list *rl)
+{
+
+ return (ofw_bus_reg_to_rl_helper(dev, node, acells, scells, rl, "reg"));
+}
+
+int
+ofw_bus_assigned_addresses_to_rl(device_t dev, phandle_t node, pcell_t acells,
+ pcell_t scells, struct resource_list *rl)
+{
+
+ return (ofw_bus_reg_to_rl_helper(dev, node, acells, scells,
+ rl, "assigned-addresses"));
+}
+
/*
* Get interrupt parent for given node.
* Returns 0 if interrupt parent doesn't exist.
@@ -569,7 +588,7 @@ ofw_bus_intr_to_rl(device_t dev, phandle_t node,
int err, i, irqnum, nintr, rid;
boolean_t extended;
- nintr = OF_getencprop_alloc(node, "interrupts", sizeof(*intr),
+ nintr = OF_getencprop_alloc_multi(node, "interrupts", sizeof(*intr),
(void **)&intr);
if (nintr > 0) {
iparent = ofw_bus_find_iparent(node);
@@ -592,7 +611,7 @@ ofw_bus_intr_to_rl(device_t dev, phandle_t node,
}
extended = false;
} else {
- nintr = OF_getencprop_alloc(node, "interrupts-extended",
+ nintr = OF_getencprop_alloc_multi(node, "interrupts-extended",
sizeof(*intr), (void **)&intr);
if (nintr <= 0)
return (0);
@@ -635,7 +654,7 @@ ofw_bus_intr_by_rid(device_t dev, phandle_t node, int wanted_rid,
int err, i, nintr, rid;
boolean_t extended;
- nintr = OF_getencprop_alloc(node, "interrupts", sizeof(*intr),
+ nintr = OF_getencprop_alloc_multi(node, "interrupts", sizeof(*intr),
(void **)&intr);
if (nintr > 0) {
iparent = ofw_bus_find_iparent(node);
@@ -658,7 +677,7 @@ ofw_bus_intr_by_rid(device_t dev, phandle_t node, int wanted_rid,
}
extended = false;
} else {
- nintr = OF_getencprop_alloc(node, "interrupts-extended",
+ nintr = OF_getencprop_alloc_multi(node, "interrupts-extended",
sizeof(*intr), (void **)&intr);
if (nintr <= 0)
return (ESRCH);
@@ -705,7 +724,7 @@ ofw_bus_find_child(phandle_t start, const char *child_name)
phandle_t child;
for (child = OF_child(start); child != 0; child = OF_peer(child)) {
- ret = OF_getprop_alloc(child, "name", sizeof(*name), (void **)&name);
+ ret = OF_getprop_alloc(child, "name", (void **)&name);
if (ret == -1)
continue;
if (strcmp(name, child_name) == 0) {
@@ -806,7 +825,7 @@ ofw_bus_parse_xref_list_internal(phandle_t node, const char *list_name,
int rv, i, j, nelems, cnt;
elems = NULL;
- nelems = OF_getencprop_alloc(node, list_name, sizeof(*elems),
+ nelems = OF_getencprop_alloc_multi(node, list_name, sizeof(*elems),
(void **)&elems);
if (nelems <= 0)
return (ENOENT);
@@ -901,7 +920,7 @@ ofw_bus_find_string_index(phandle_t node, const char *list_name,
int rv, i, cnt, nelems;
elems = NULL;
- nelems = OF_getprop_alloc(node, list_name, 1, (void **)&elems);
+ nelems = OF_getprop_alloc(node, list_name, (void **)&elems);
if (nelems <= 0)
return (ENOENT);
@@ -932,7 +951,7 @@ ofw_bus_string_list_to_array(phandle_t node, const char *list_name,
int i, cnt, nelems, len;
elems = NULL;
- nelems = OF_getprop_alloc(node, list_name, 1, (void **)&elems);
+ nelems = OF_getprop_alloc(node, list_name, (void **)&elems);
if (nelems <= 0)
return (nelems);
diff --git a/freebsd/sys/dev/ofw/ofw_bus_subr.h b/freebsd/sys/dev/ofw/ofw_bus_subr.h
index 04f5a75b..7bf66a10 100644
--- a/freebsd/sys/dev/ofw/ofw_bus_subr.h
+++ b/freebsd/sys/dev/ofw/ofw_bus_subr.h
@@ -95,6 +95,8 @@ int ofw_bus_msimap(phandle_t, uint16_t, phandle_t *, uint32_t *);
/* Routines for parsing device-tree data into resource lists. */
int ofw_bus_reg_to_rl(device_t, phandle_t, pcell_t, pcell_t,
struct resource_list *);
+int ofw_bus_assigned_addresses_to_rl(device_t, phandle_t, pcell_t, pcell_t,
+ struct resource_list *);
int ofw_bus_intr_to_rl(device_t, phandle_t, struct resource_list *, int *);
int ofw_bus_intr_by_rid(device_t, phandle_t, int, phandle_t *, int *,
pcell_t **);
diff --git a/freebsd/sys/dev/ofw/ofw_fdt.c b/freebsd/sys/dev/ofw/ofw_fdt.c
index 8878b5c9..b1bbadee 100644
--- a/freebsd/sys/dev/ofw/ofw_fdt.c
+++ b/freebsd/sys/dev/ofw/ofw_fdt.c
@@ -134,7 +134,7 @@ sysctl_register_fdt_oid(void *arg)
CTLTYPE_OPAQUE | CTLFLAG_RD, NULL, 0, sysctl_handle_dtb, "",
"Device Tree Blob");
}
-SYSINIT(dtb_oid, SI_SUB_KMEM, SI_ORDER_ANY, sysctl_register_fdt_oid, 0);
+SYSINIT(dtb_oid, SI_SUB_KMEM, SI_ORDER_ANY, sysctl_register_fdt_oid, NULL);
static int
ofw_fdt_init(ofw_t ofw, void *data)
diff --git a/freebsd/sys/dev/ofw/openfirm.c b/freebsd/sys/dev/ofw/openfirm.c
index 406e8dd6..9cc7dbdc 100644
--- a/freebsd/sys/dev/ofw/openfirm.c
+++ b/freebsd/sys/dev/ofw/openfirm.c
@@ -442,7 +442,7 @@ OF_searchprop(phandle_t node, const char *propname, void *buf, size_t len)
}
ssize_t
-OF_searchencprop(phandle_t node, const char *propname, void *buf, size_t len)
+OF_searchencprop(phandle_t node, const char *propname, pcell_t *buf, size_t len)
{
ssize_t rv;
@@ -454,11 +454,35 @@ OF_searchencprop(phandle_t node, const char *propname, void *buf, size_t len)
/*
* Store the value of a property of a package into newly allocated memory
+ * (using the M_OFWPROP malloc pool and M_WAITOK).
+ */
+ssize_t
+OF_getprop_alloc(phandle_t package, const char *propname, void **buf)
+{
+ int len;
+
+ *buf = NULL;
+ if ((len = OF_getproplen(package, propname)) == -1)
+ return (-1);
+
+ if (len > 0) {
+ *buf = malloc(len, M_OFWPROP, M_WAITOK);
+ if (OF_getprop(package, propname, *buf, len) == -1) {
+ free(*buf, M_OFWPROP);
+ *buf = NULL;
+ return (-1);
+ }
+ }
+ return (len);
+}
+
+/*
+ * Store the value of a property of a package into newly allocated memory
* (using the M_OFWPROP malloc pool and M_WAITOK). elsz is the size of a
* single element, the number of elements is return in number.
*/
ssize_t
-OF_getprop_alloc(phandle_t package, const char *propname, int elsz, void **buf)
+OF_getprop_alloc_multi(phandle_t package, const char *propname, int elsz, void **buf)
{
int len;
@@ -467,30 +491,41 @@ OF_getprop_alloc(phandle_t package, const char *propname, int elsz, void **buf)
len % elsz != 0)
return (-1);
- *buf = malloc(len, M_OFWPROP, M_WAITOK);
- if (OF_getprop(package, propname, *buf, len) == -1) {
- free(*buf, M_OFWPROP);
- *buf = NULL;
- return (-1);
+ if (len > 0) {
+ *buf = malloc(len, M_OFWPROP, M_WAITOK);
+ if (OF_getprop(package, propname, *buf, len) == -1) {
+ free(*buf, M_OFWPROP);
+ *buf = NULL;
+ return (-1);
+ }
}
return (len / elsz);
}
ssize_t
-OF_getencprop_alloc(phandle_t package, const char *name, int elsz, void **buf)
+OF_getencprop_alloc(phandle_t package, const char *name, void **buf)
+{
+ ssize_t ret;
+
+ ret = OF_getencprop_alloc_multi(package, name, sizeof(pcell_t),
+ buf);
+ if (ret < 0)
+ return (ret);
+ else
+ return (ret * sizeof(pcell_t));
+}
+
+ssize_t
+OF_getencprop_alloc_multi(phandle_t package, const char *name, int elsz,
+ void **buf)
{
ssize_t retval;
pcell_t *cell;
int i;
- retval = OF_getprop_alloc(package, name, elsz, buf);
+ retval = OF_getprop_alloc_multi(package, name, elsz, buf);
if (retval == -1)
return (-1);
- if (retval * elsz % 4 != 0) {
- free(*buf, M_OFWPROP);
- *buf = NULL;
- return (-1);
- }
cell = *buf;
for (i = 0; i < retval * elsz / 4; i++)
diff --git a/freebsd/sys/dev/ofw/openfirm.h b/freebsd/sys/dev/ofw/openfirm.h
index e1701164..f043197a 100644
--- a/freebsd/sys/dev/ofw/openfirm.h
+++ b/freebsd/sys/dev/ofw/openfirm.h
@@ -114,10 +114,14 @@ int OF_hasprop(phandle_t node, const char *propname);
ssize_t OF_searchprop(phandle_t node, const char *propname, void *buf,
size_t len);
ssize_t OF_searchencprop(phandle_t node, const char *propname,
- void *buf, size_t len);
+ pcell_t *buf, size_t len);
ssize_t OF_getprop_alloc(phandle_t node, const char *propname,
+ void **buf);
+ssize_t OF_getprop_alloc_multi(phandle_t node, const char *propname,
int elsz, void **buf);
ssize_t OF_getencprop_alloc(phandle_t node, const char *propname,
+ void **buf);
+ssize_t OF_getencprop_alloc_multi(phandle_t node, const char *propname,
int elsz, void **buf);
void OF_prop_free(void *buf);
int OF_nextprop(phandle_t node, const char *propname, char *buf,
diff --git a/freebsd/sys/dev/pci/pci_pci.c b/freebsd/sys/dev/pci/pci_pci.c
index 20364cf9..ec52e1fb 100644
--- a/freebsd/sys/dev/pci/pci_pci.c
+++ b/freebsd/sys/dev/pci/pci_pci.c
@@ -2547,6 +2547,22 @@ pcib_enable_ari(struct pcib_softc *sc, uint32_t pcie_pos)
int
pcib_maxslots(device_t dev)
{
+#if !defined(__amd64__) && !defined(__i386__)
+ uint32_t pcie_pos;
+ uint16_t val;
+
+ /*
+ * If this is a PCIe rootport or downstream switch port, there's only
+ * one slot permitted.
+ */
+ if (pci_find_cap(dev, PCIY_EXPRESS, &pcie_pos) == 0) {
+ val = pci_read_config(dev, pcie_pos + PCIER_FLAGS, 2);
+ val &= PCIEM_FLAGS_TYPE;
+ if (val == PCIEM_TYPE_ROOT_PORT ||
+ val == PCIEM_TYPE_DOWNSTREAM_PORT)
+ return (0);
+ }
+#endif
return (PCI_SLOTMAX);
}
@@ -2560,7 +2576,7 @@ pcib_ari_maxslots(device_t dev)
if (sc->flags & PCIB_ENABLE_ARI)
return (PCIE_ARI_SLOTMAX);
else
- return (PCI_SLOTMAX);
+ return (pcib_maxslots(dev));
}
static int
diff --git a/freebsd/sys/dev/pci/pci_user.c b/freebsd/sys/dev/pci/pci_user.c
index e6297bd7..c9d500a8 100644
--- a/freebsd/sys/dev/pci/pci_user.c
+++ b/freebsd/sys/dev/pci/pci_user.c
@@ -32,7 +32,6 @@
__FBSDID("$FreeBSD$");
#include <rtems/bsd/local/opt_bus.h> /* XXX trim includes */
-#include <rtems/bsd/local/opt_compat.h>
#include <sys/param.h>
#include <sys/systm.h>
@@ -68,8 +67,6 @@ __FBSDID("$FreeBSD$");
static d_open_t pci_open;
static d_close_t pci_close;
-static int pci_conf_match(struct pci_match_conf *matches, int num_matches,
- struct pci_conf *match_buf);
static d_ioctl_t pci_ioctl;
struct cdevsw pcicdev = {
@@ -109,7 +106,7 @@ pci_close(struct cdev *dev, int flag, int devtype, struct thread *td)
* This function returns 1 on failure, 0 on success.
*/
static int
-pci_conf_match(struct pci_match_conf *matches, int num_matches,
+pci_conf_match_native(struct pci_match_conf *matches, int num_matches,
struct pci_conf *match_buf)
{
int i;
@@ -278,9 +275,6 @@ struct pci_conf_io32 {
#define PCIOCREAD_OLD _IOWR('p', 2, struct pci_io_old)
#define PCIOCWRITE_OLD _IOWR('p', 3, struct pci_io_old)
-static int pci_conf_match_old(struct pci_match_conf_old *matches,
- int num_matches, struct pci_conf *match_buf);
-
static int
pci_conf_match_old(struct pci_match_conf_old *matches, int num_matches,
struct pci_conf *match_buf)
@@ -408,7 +402,44 @@ pci_conf_match_old32(struct pci_match_conf_old32 *matches, int num_matches,
return (1);
}
#endif /* COMPAT_FREEBSD32 */
-#endif /* PRE7_COMPAT */
+#endif /* !PRE7_COMPAT */
+
+union pci_conf_union {
+ struct pci_conf pc;
+#ifdef PRE7_COMPAT
+ struct pci_conf_old pco;
+#ifdef COMPAT_FREEBSD32
+ struct pci_conf_old32 pco32;
+#endif
+#endif
+};
+
+static int
+pci_conf_match(u_long cmd, struct pci_match_conf *matches, int num_matches,
+ struct pci_conf *match_buf)
+{
+
+ switch (cmd) {
+ case PCIOCGETCONF:
+ return (pci_conf_match_native(
+ (struct pci_match_conf *)matches, num_matches, match_buf));
+#ifdef PRE7_COMPAT
+ case PCIOCGETCONF_OLD:
+ return (pci_conf_match_old(
+ (struct pci_match_conf_old *)matches, num_matches,
+ match_buf));
+#ifdef COMPAT_FREEBSD32
+ case PCIOCGETCONF_OLD32:
+ return (pci_conf_match_old32(
+ (struct pci_match_conf_old32 *)matches, num_matches,
+ match_buf));
+#endif
+#endif
+ default:
+ /* programmer error */
+ return (0);
+ }
+}
static int
pci_list_vpd(device_t dev, struct pci_list_vpd_io *lvio)
@@ -493,11 +524,184 @@ pci_list_vpd(device_t dev, struct pci_list_vpd_io *lvio)
return (0);
}
+static size_t
+pci_match_conf_size(u_long cmd)
+{
+
+ switch (cmd) {
+ case PCIOCGETCONF:
+ return (sizeof(struct pci_match_conf));
+#ifdef PRE7_COMPAT
+ case PCIOCGETCONF_OLD:
+ return (sizeof(struct pci_match_conf_old));
+#ifdef COMPAT_FREEBSD32
+ case PCIOCGETCONF_OLD32:
+ return (sizeof(struct pci_match_conf_old32));
+#endif
+#endif
+ default:
+ /* programmer error */
+ return (0);
+ }
+}
+
+static size_t
+pci_conf_size(u_long cmd)
+{
+
+ switch (cmd) {
+ case PCIOCGETCONF:
+ return (sizeof(struct pci_conf));
+#ifdef PRE7_COMPAT
+ case PCIOCGETCONF_OLD:
+ return (sizeof(struct pci_conf_old));
+#ifdef COMPAT_FREEBSD32
+ case PCIOCGETCONF_OLD32:
+ return (sizeof(struct pci_conf_old32));
+#endif
+#endif
+ default:
+ /* programmer error */
+ return (0);
+ }
+}
+
+static void
+pci_conf_io_init(struct pci_conf_io *cio, caddr_t data, u_long cmd)
+{
+#if defined(PRE7_COMPAT) && defined(COMPAT_FREEBSD32)
+ struct pci_conf_io32 *cio32;
+#endif
+
+ switch (cmd) {
+ case PCIOCGETCONF:
+#ifdef PRE7_COMPAT
+ case PCIOCGETCONF_OLD:
+#endif
+ *cio = *(struct pci_conf_io *)data;
+ return;
+
+#if defined(PRE7_COMPAT) && defined(COMPAT_FREEBSD32)
+ case PCIOCGETCONF_OLD32:
+ cio32 = (struct pci_conf_io32 *)data;
+ cio->pat_buf_len = cio32->pat_buf_len;
+ cio->num_patterns = cio32->num_patterns;
+ cio->patterns = (void *)(uintptr_t)cio32->patterns;
+ cio->match_buf_len = cio32->match_buf_len;
+ cio->num_matches = cio32->num_matches;
+ cio->matches = (void *)(uintptr_t)cio32->matches;
+ cio->offset = cio32->offset;
+ cio->generation = cio32->generation;
+ cio->status = cio32->status;
+ return;
+#endif
+
+ default:
+ /* programmer error */
+ return;
+ }
+}
+
+static void
+pci_conf_io_update_data(const struct pci_conf_io *cio, caddr_t data,
+ u_long cmd)
+{
+ struct pci_conf_io *d_cio;
+#if defined(PRE7_COMPAT) && defined(COMPAT_FREEBSD32)
+ struct pci_conf_io32 *cio32;
+#endif
+
+ switch (cmd) {
+ case PCIOCGETCONF:
+#ifdef PRE7_COMPAT
+ case PCIOCGETCONF_OLD:
+#endif
+ d_cio = (struct pci_conf_io *)data;
+ d_cio->status = cio->status;
+ d_cio->generation = cio->generation;
+ d_cio->offset = cio->offset;
+ d_cio->num_matches = cio->num_matches;
+ return;
+
+#if defined(PRE7_COMPAT) && defined(COMPAT_FREEBSD32)
+ case PCIOCGETCONF_OLD32:
+ cio32 = (struct pci_conf_io32 *)data;
+
+ cio32->status = cio->status;
+ cio32->generation = cio->generation;
+ cio32->offset = cio->offset;
+ cio32->num_matches = cio->num_matches;
+ return;
+#endif
+
+ default:
+ /* programmer error */
+ return;
+ }
+}
+
+static void
+pci_conf_for_copyout(const struct pci_conf *pcp, union pci_conf_union *pcup,
+ u_long cmd)
+{
+
+ memset(pcup, 0, sizeof(*pcup));
+
+ switch (cmd) {
+ case PCIOCGETCONF:
+ pcup->pc = *pcp;
+ return;
+
+#ifdef PRE7_COMPAT
+#ifdef COMPAT_FREEBSD32
+ case PCIOCGETCONF_OLD32:
+ pcup->pco32.pc_sel.pc_bus = pcp->pc_sel.pc_bus;
+ pcup->pco32.pc_sel.pc_dev = pcp->pc_sel.pc_dev;
+ pcup->pco32.pc_sel.pc_func = pcp->pc_sel.pc_func;
+ pcup->pco32.pc_hdr = pcp->pc_hdr;
+ pcup->pco32.pc_subvendor = pcp->pc_subvendor;
+ pcup->pco32.pc_subdevice = pcp->pc_subdevice;
+ pcup->pco32.pc_vendor = pcp->pc_vendor;
+ pcup->pco32.pc_device = pcp->pc_device;
+ pcup->pco32.pc_class = pcp->pc_class;
+ pcup->pco32.pc_subclass = pcp->pc_subclass;
+ pcup->pco32.pc_progif = pcp->pc_progif;
+ pcup->pco32.pc_revid = pcp->pc_revid;
+ strlcpy(pcup->pco32.pd_name, pcp->pd_name,
+ sizeof(pcup->pco32.pd_name));
+ pcup->pco32.pd_unit = (uint32_t)pcp->pd_unit;
+ return;
+
+#endif /* COMPAT_FREEBSD32 */
+ case PCIOCGETCONF_OLD:
+ pcup->pco.pc_sel.pc_bus = pcp->pc_sel.pc_bus;
+ pcup->pco.pc_sel.pc_dev = pcp->pc_sel.pc_dev;
+ pcup->pco.pc_sel.pc_func = pcp->pc_sel.pc_func;
+ pcup->pco.pc_hdr = pcp->pc_hdr;
+ pcup->pco.pc_subvendor = pcp->pc_subvendor;
+ pcup->pco.pc_subdevice = pcp->pc_subdevice;
+ pcup->pco.pc_vendor = pcp->pc_vendor;
+ pcup->pco.pc_device = pcp->pc_device;
+ pcup->pco.pc_class = pcp->pc_class;
+ pcup->pco.pc_subclass = pcp->pc_subclass;
+ pcup->pco.pc_progif = pcp->pc_progif;
+ pcup->pco.pc_revid = pcp->pc_revid;
+ strlcpy(pcup->pco.pd_name, pcp->pd_name,
+ sizeof(pcup->pco.pd_name));
+ pcup->pco.pd_unit = pcp->pd_unit;
+ return;
+#endif /* PRE7_COMPAT */
+
+ default:
+ /* programmer error */
+ return;
+ }
+}
+
static int
pci_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td)
{
device_t pcidev;
- void *confdata;
const char *name;
struct devlist *devlist_head;
struct pci_conf_io *cio = NULL;
@@ -507,31 +711,25 @@ pci_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *t
struct pci_list_vpd_io *lvio;
struct pci_match_conf *pattern_buf;
struct pci_map *pm;
- size_t confsz, iolen, pbufsz;
+ size_t confsz, iolen;
int error, ionum, i, num_patterns;
+ union pci_conf_union pcu;
#ifdef PRE7_COMPAT
-#ifdef COMPAT_FREEBSD32
- struct pci_conf_io32 *cio32 = NULL;
- struct pci_conf_old32 conf_old32;
- struct pci_match_conf_old32 *pattern_buf_old32 = NULL;
-#endif
- struct pci_conf_old conf_old;
struct pci_io iodata;
struct pci_io_old *io_old;
- struct pci_match_conf_old *pattern_buf_old = NULL;
io_old = NULL;
#endif
if (!(flag & FWRITE)) {
switch (cmd) {
+ case PCIOCGETCONF:
#ifdef PRE7_COMPAT
+ case PCIOCGETCONF_OLD:
#ifdef COMPAT_FREEBSD32
case PCIOCGETCONF_OLD32:
#endif
- case PCIOCGETCONF_OLD:
#endif
- case PCIOCGETCONF:
case PCIOCGETBAR:
case PCIOCLISTVPD:
break;
@@ -540,39 +738,18 @@ pci_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *t
}
}
- switch (cmd) {
-#ifdef PRE7_COMPAT
-#ifdef COMPAT_FREEBSD32
- case PCIOCGETCONF_OLD32:
- cio32 = (struct pci_conf_io32 *)data;
- cio = malloc(sizeof(struct pci_conf_io), M_TEMP, M_WAITOK);
- cio->pat_buf_len = cio32->pat_buf_len;
- cio->num_patterns = cio32->num_patterns;
- cio->patterns = (void *)(uintptr_t)cio32->patterns;
- cio->match_buf_len = cio32->match_buf_len;
- cio->num_matches = cio32->num_matches;
- cio->matches = (void *)(uintptr_t)cio32->matches;
- cio->offset = cio32->offset;
- cio->generation = cio32->generation;
- cio->status = cio32->status;
- cio32->num_matches = 0;
- break;
-#endif
- case PCIOCGETCONF_OLD:
-#endif
- case PCIOCGETCONF:
- cio = (struct pci_conf_io *)data;
- }
switch (cmd) {
+ case PCIOCGETCONF:
#ifdef PRE7_COMPAT
+ case PCIOCGETCONF_OLD:
#ifdef COMPAT_FREEBSD32
case PCIOCGETCONF_OLD32:
#endif
- case PCIOCGETCONF_OLD:
#endif
- case PCIOCGETCONF:
-
+ cio = malloc(sizeof(struct pci_conf_io), M_TEMP,
+ M_WAITOK | M_ZERO);
+ pci_conf_io_init(cio, data, cmd);
pattern_buf = NULL;
num_patterns = 0;
dinfo = NULL;
@@ -611,17 +788,7 @@ pci_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *t
* multiple of sizeof(struct pci_conf) in case the user
* didn't specify a multiple of that size.
*/
-#ifdef PRE7_COMPAT
-#ifdef COMPAT_FREEBSD32
- if (cmd == PCIOCGETCONF_OLD32)
- confsz = sizeof(struct pci_conf_old32);
- else
-#endif
- if (cmd == PCIOCGETCONF_OLD)
- confsz = sizeof(struct pci_conf_old);
- else
-#endif
- confsz = sizeof(struct pci_conf);
+ confsz = pci_conf_size(cmd);
iolen = min(cio->match_buf_len - (cio->match_buf_len % confsz),
pci_numdevs * confsz);
@@ -650,18 +817,8 @@ pci_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *t
* it's far more likely to just catch folks that
* updated their kernel but not their userland.
*/
-#ifdef PRE7_COMPAT
-#ifdef COMPAT_FREEBSD32
- if (cmd == PCIOCGETCONF_OLD32)
- pbufsz = sizeof(struct pci_match_conf_old32);
- else
-#endif
- if (cmd == PCIOCGETCONF_OLD)
- pbufsz = sizeof(struct pci_match_conf_old);
- else
-#endif
- pbufsz = sizeof(struct pci_match_conf);
- if (cio->num_patterns * pbufsz != cio->pat_buf_len) {
+ if (cio->num_patterns * pci_match_conf_size(cmd) !=
+ cio->pat_buf_len) {
/* The user made a mistake, return an error. */
cio->status = PCI_GETCONF_ERROR;
error = EINVAL;
@@ -671,28 +828,10 @@ pci_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *t
/*
* Allocate a buffer to hold the patterns.
*/
-#ifdef PRE7_COMPAT
-#ifdef COMPAT_FREEBSD32
- if (cmd == PCIOCGETCONF_OLD32) {
- pattern_buf_old32 = malloc(cio->pat_buf_len,
- M_TEMP, M_WAITOK);
- error = copyin(cio->patterns,
- pattern_buf_old32, cio->pat_buf_len);
- } else
-#endif /* COMPAT_FREEBSD32 */
- if (cmd == PCIOCGETCONF_OLD) {
- pattern_buf_old = malloc(cio->pat_buf_len,
- M_TEMP, M_WAITOK);
- error = copyin(cio->patterns,
- pattern_buf_old, cio->pat_buf_len);
- } else
-#endif /* PRE7_COMPAT */
- {
- pattern_buf = malloc(cio->pat_buf_len, M_TEMP,
- M_WAITOK);
- error = copyin(cio->patterns, pattern_buf,
- cio->pat_buf_len);
- }
+ pattern_buf = malloc(cio->pat_buf_len, M_TEMP,
+ M_WAITOK);
+ error = copyin(cio->patterns, pattern_buf,
+ cio->pat_buf_len);
if (error != 0) {
error = EINVAL;
goto getconfexit;
@@ -735,27 +874,9 @@ pci_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *t
dinfo->conf.pd_unit = 0;
}
-#ifdef PRE7_COMPAT
- if (
-#ifdef COMPAT_FREEBSD32
- (cmd == PCIOCGETCONF_OLD32 &&
- (pattern_buf_old32 == NULL ||
- pci_conf_match_old32(pattern_buf_old32,
- num_patterns, &dinfo->conf) == 0)) ||
-#endif
- (cmd == PCIOCGETCONF_OLD &&
- (pattern_buf_old == NULL ||
- pci_conf_match_old(pattern_buf_old, num_patterns,
- &dinfo->conf) == 0)) ||
- (cmd == PCIOCGETCONF &&
- (pattern_buf == NULL ||
- pci_conf_match(pattern_buf, num_patterns,
- &dinfo->conf) == 0))) {
-#else
if (pattern_buf == NULL ||
- pci_conf_match(pattern_buf, num_patterns,
+ pci_conf_match(cmd, pattern_buf, num_patterns,
&dinfo->conf) == 0) {
-#endif
/*
* If we've filled up the user's buffer,
* break out at this point. Since we've
@@ -769,79 +890,8 @@ pci_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *t
break;
}
-#ifdef PRE7_COMPAT
-#ifdef COMPAT_FREEBSD32
- if (cmd == PCIOCGETCONF_OLD32) {
- memset(&conf_old32, 0,
- sizeof(conf_old32));
- conf_old32.pc_sel.pc_bus =
- dinfo->conf.pc_sel.pc_bus;
- conf_old32.pc_sel.pc_dev =
- dinfo->conf.pc_sel.pc_dev;
- conf_old32.pc_sel.pc_func =
- dinfo->conf.pc_sel.pc_func;
- conf_old32.pc_hdr = dinfo->conf.pc_hdr;
- conf_old32.pc_subvendor =
- dinfo->conf.pc_subvendor;
- conf_old32.pc_subdevice =
- dinfo->conf.pc_subdevice;
- conf_old32.pc_vendor =
- dinfo->conf.pc_vendor;
- conf_old32.pc_device =
- dinfo->conf.pc_device;
- conf_old32.pc_class =
- dinfo->conf.pc_class;
- conf_old32.pc_subclass =
- dinfo->conf.pc_subclass;
- conf_old32.pc_progif =
- dinfo->conf.pc_progif;
- conf_old32.pc_revid =
- dinfo->conf.pc_revid;
- strncpy(conf_old32.pd_name,
- dinfo->conf.pd_name,
- sizeof(conf_old32.pd_name));
- conf_old32.pd_name[PCI_MAXNAMELEN] = 0;
- conf_old32.pd_unit =
- (uint32_t)dinfo->conf.pd_unit;
- confdata = &conf_old32;
- } else
-#endif /* COMPAT_FREEBSD32 */
- if (cmd == PCIOCGETCONF_OLD) {
- memset(&conf_old, 0, sizeof(conf_old));
- conf_old.pc_sel.pc_bus =
- dinfo->conf.pc_sel.pc_bus;
- conf_old.pc_sel.pc_dev =
- dinfo->conf.pc_sel.pc_dev;
- conf_old.pc_sel.pc_func =
- dinfo->conf.pc_sel.pc_func;
- conf_old.pc_hdr = dinfo->conf.pc_hdr;
- conf_old.pc_subvendor =
- dinfo->conf.pc_subvendor;
- conf_old.pc_subdevice =
- dinfo->conf.pc_subdevice;
- conf_old.pc_vendor =
- dinfo->conf.pc_vendor;
- conf_old.pc_device =
- dinfo->conf.pc_device;
- conf_old.pc_class =
- dinfo->conf.pc_class;
- conf_old.pc_subclass =
- dinfo->conf.pc_subclass;
- conf_old.pc_progif =
- dinfo->conf.pc_progif;
- conf_old.pc_revid =
- dinfo->conf.pc_revid;
- strncpy(conf_old.pd_name,
- dinfo->conf.pd_name,
- sizeof(conf_old.pd_name));
- conf_old.pd_name[PCI_MAXNAMELEN] = 0;
- conf_old.pd_unit =
- dinfo->conf.pd_unit;
- confdata = &conf_old;
- } else
-#endif /* PRE7_COMPAT */
- confdata = &dinfo->conf;
- error = copyout(confdata,
+ pci_conf_for_copyout(&dinfo->conf, &pcu, cmd);
+ error = copyout(&pcu,
(caddr_t)cio->matches +
confsz * cio->num_matches, confsz);
if (error)
@@ -874,23 +924,9 @@ pci_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *t
cio->status = PCI_GETCONF_MORE_DEVS;
getconfexit:
-#ifdef PRE7_COMPAT
-#ifdef COMPAT_FREEBSD32
- if (cmd == PCIOCGETCONF_OLD32) {
- cio32->status = cio->status;
- cio32->generation = cio->generation;
- cio32->offset = cio->offset;
- cio32->num_matches = cio->num_matches;
- free(cio, M_TEMP);
- }
- if (pattern_buf_old32 != NULL)
- free(pattern_buf_old32, M_TEMP);
-#endif
- if (pattern_buf_old != NULL)
- free(pattern_buf_old, M_TEMP);
-#endif
- if (pattern_buf != NULL)
- free(pattern_buf, M_TEMP);
+ pci_conf_io_update_data(cio, data, cmd);
+ free(cio, M_TEMP);
+ free(pattern_buf, M_TEMP);
break;
diff --git a/freebsd/sys/dev/re/if_re.c b/freebsd/sys/dev/re/if_re.c
index c8bb6db7..5aa24349 100644
--- a/freebsd/sys/dev/re/if_re.c
+++ b/freebsd/sys/dev/re/if_re.c
@@ -141,6 +141,8 @@ __FBSDID("$FreeBSD$");
#include <net/bpf.h>
+#include <netinet/netdump/netdump.h>
+
#include <machine/bus.h>
#include <machine/resource.h>
#include <sys/bus.h>
@@ -281,6 +283,7 @@ static void re_tick (void *);
static void re_int_task (void *, int);
static void re_start (struct ifnet *);
static void re_start_locked (struct ifnet *);
+static void re_start_tx (struct rl_softc *);
static int re_ioctl (struct ifnet *, u_long, caddr_t);
static void re_init (void *);
static void re_init_locked (struct rl_softc *);
@@ -309,6 +312,8 @@ static void re_setwol (struct rl_softc *);
static void re_clrwol (struct rl_softc *);
static void re_set_linkspeed (struct rl_softc *);
+NETDUMP_DEFINE(re);
+
#ifdef DEV_NETMAP /* see ixgbe.c for details */
#include <dev/netmap/if_re_netmap.h>
MODULE_DEPEND(re, netmap, 1, 1, 1);
@@ -682,7 +687,7 @@ re_set_rxmode(struct rl_softc *sc)
}
if_maddr_rlock(ifp);
- TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
+ CK_STAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
if (ifma->ifma_addr->sa_family != AF_LINK)
continue;
h = ether_crc32_be(LLADDR((struct sockaddr_dl *)
@@ -1739,8 +1744,11 @@ re_attach(device_t dev)
if (error) {
device_printf(dev, "couldn't set up irq\n");
ether_ifdetach(ifp);
+ goto fail;
}
+ NETDUMP_SET(ifp, re);
+
fail:
if (error)
re_detach(dev);
@@ -2935,7 +2943,7 @@ re_start_locked(struct ifnet *ifp)
#ifdef DEV_NETMAP
/* XXX is this necessary ? */
if (ifp->if_capenable & IFCAP_NETMAP) {
- struct netmap_kring *kring = &NA(ifp)->tx_rings[0];
+ struct netmap_kring *kring = NA(ifp)->tx_rings[0];
if (sc->rl_ldata.rl_tx_prodidx != kring->nr_hwcur) {
/* kick the tx unit */
CSR_WRITE_1(sc, sc->rl_txstart, RL_TXSTART_START);
@@ -2983,8 +2991,14 @@ re_start_locked(struct ifnet *ifp)
return;
}
- /* Flush the TX descriptors */
+ re_start_tx(sc);
+}
+static void
+re_start_tx(struct rl_softc *sc)
+{
+
+ /* Flush the TX descriptors */
bus_dmamap_sync(sc->rl_ldata.rl_tx_list_tag,
sc->rl_ldata.rl_tx_list_map,
BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD);
@@ -4080,3 +4094,59 @@ sysctl_hw_re_int_mod(SYSCTL_HANDLER_ARGS)
return (sysctl_int_range(oidp, arg1, arg2, req, RL_TIMER_MIN,
RL_TIMER_MAX));
}
+
+#ifdef NETDUMP
+static void
+re_netdump_init(struct ifnet *ifp, int *nrxr, int *ncl, int *clsize)
+{
+ struct rl_softc *sc;
+
+ sc = if_getsoftc(ifp);
+ RL_LOCK(sc);
+ *nrxr = sc->rl_ldata.rl_rx_desc_cnt;
+ *ncl = NETDUMP_MAX_IN_FLIGHT;
+ *clsize = (ifp->if_mtu > RL_MTU &&
+ (sc->rl_flags & RL_FLAG_JUMBOV2) != 0) ? MJUM9BYTES : MCLBYTES;
+ RL_UNLOCK(sc);
+}
+
+static void
+re_netdump_event(struct ifnet *ifp __unused, enum netdump_ev event __unused)
+{
+}
+
+static int
+re_netdump_transmit(struct ifnet *ifp, struct mbuf *m)
+{
+ struct rl_softc *sc;
+ int error;
+
+ sc = if_getsoftc(ifp);
+ if ((if_getdrvflags(ifp) & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
+ IFF_DRV_RUNNING || (sc->rl_flags & RL_FLAG_LINK) == 0)
+ return (EBUSY);
+
+ error = re_encap(sc, &m);
+ if (error == 0)
+ re_start_tx(sc);
+ return (error);
+}
+
+static int
+re_netdump_poll(struct ifnet *ifp, int count)
+{
+ struct rl_softc *sc;
+ int error;
+
+ sc = if_getsoftc(ifp);
+ if ((if_getdrvflags(ifp) & IFF_DRV_RUNNING) == 0 ||
+ (sc->rl_flags & RL_FLAG_LINK) == 0)
+ return (EBUSY);
+
+ re_txeof(sc);
+ error = re_rxeof(sc, NULL);
+ if (error != 0 && error != EAGAIN)
+ return (error);
+ return (0);
+}
+#endif /* NETDUMP */
diff --git a/freebsd/sys/dev/rtwn/if_rtwn_rx.c b/freebsd/sys/dev/rtwn/if_rtwn_rx.c
index fb260596..512292ce 100644
--- a/freebsd/sys/dev/rtwn/if_rtwn_rx.c
+++ b/freebsd/sys/dev/rtwn/if_rtwn_rx.c
@@ -389,7 +389,7 @@ rtwn_set_multi(struct rtwn_softc *sc)
TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
ifp = vap->iv_ifp;
if_maddr_rlock(ifp);
- TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
+ CK_STAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
caddr_t dl;
uint8_t pos;
diff --git a/freebsd/sys/dev/tsec/if_tsec.c b/freebsd/sys/dev/tsec/if_tsec.c
index e07c21ce..c18c950f 100644
--- a/freebsd/sys/dev/tsec/if_tsec.c
+++ b/freebsd/sys/dev/tsec/if_tsec.c
@@ -1943,7 +1943,7 @@ tsec_setup_multicast(struct tsec_softc *sc)
}
if_maddr_rlock(ifp);
- TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
+ CK_STAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
if (ifma->ifma_addr->sa_family != AF_LINK)
continue;
diff --git a/freebsd/sys/dev/usb/input/ukbd.c b/freebsd/sys/dev/usb/input/ukbd.c
index 5cb2636c..76fe76b6 100644
--- a/freebsd/sys/dev/usb/input/ukbd.c
+++ b/freebsd/sys/dev/usb/input/ukbd.c
@@ -41,7 +41,6 @@ __FBSDID("$FreeBSD$");
* HID spec: http://www.usb.org/developers/devclass_docs/HID1_11.pdf
*/
-#include <rtems/bsd/local/opt_compat.h>
#include <rtems/bsd/local/opt_kbd.h>
#include <rtems/bsd/local/opt_ukbd.h>
#include <rtems/bsd/local/opt_evdev.h>
diff --git a/freebsd/sys/dev/usb/input/usb_rdesc.h b/freebsd/sys/dev/usb/input/usb_rdesc.h
index 00eea122..889381e8 100644
--- a/freebsd/sys/dev/usb/input/usb_rdesc.h
+++ b/freebsd/sys/dev/usb/input/usb_rdesc.h
@@ -276,3 +276,31 @@
0x81, 0x01, /* INPUT (Constant) */\
0xc0 /* END COLLECTION */\
+/* Fixed report descriptor for Super Nintendo gamepads */
+#define UHID_SNES_REPORT_DESCR(...) \
+ 0x05, 0x01, /* Usage Page (Desktop), */\
+ 0x09, 0x04, /* Usage (Joystik), */\
+ 0xA1, 0x01, /* Collection (Application), */\
+ 0xA1, 0x02, /* Collection (Logical), */\
+ 0x14, /* Logical Minimum (0), */\
+ 0x75, 0x08, /* Report Size (8), */\
+ 0x95, 0x03, /* Report Count (3), */\
+ 0x81, 0x01, /* Input (Constant), */\
+ 0x26, 0xFF, 0x00, /* Logical Maximum (255), */\
+ 0x95, 0x02, /* Report Count (2), */\
+ 0x09, 0x30, /* Usage (X), */\
+ 0x09, 0x31, /* Usage (Y), */\
+ 0x81, 0x02, /* Input (Variable), */\
+ 0x75, 0x01, /* Report Size (1), */\
+ 0x95, 0x04, /* Report Count (4), */\
+ 0x81, 0x01, /* Input (Constant), */\
+ 0x25, 0x01, /* Logical Maximum (1), */\
+ 0x95, 0x0A, /* Report Count (10), */\
+ 0x05, 0x09, /* Usage Page (Button), */\
+ 0x19, 0x01, /* Usage Minimum (01h), */\
+ 0x29, 0x0A, /* Usage Maximum (0Ah), */\
+ 0x81, 0x02, /* Input (Variable), */\
+ 0x95, 0x0A, /* Report Count (10), */\
+ 0x81, 0x01, /* Input (Constant), */\
+ 0xC0, /* End Collection, */\
+ 0xC0 /* End Collection */
diff --git a/freebsd/sys/dev/usb/net/if_aue.c b/freebsd/sys/dev/usb/net/if_aue.c
index 69951b70..5454e2aa 100644
--- a/freebsd/sys/dev/usb/net/if_aue.c
+++ b/freebsd/sys/dev/usb/net/if_aue.c
@@ -557,7 +557,7 @@ aue_setmulti(struct usb_ether *ue)
/* now program new ones */
if_maddr_rlock(ifp);
- TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
+ CK_STAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
if (ifma->ifma_addr->sa_family != AF_LINK)
continue;
h = ether_crc32_le(LLADDR((struct sockaddr_dl *)
diff --git a/freebsd/sys/dev/usb/net/if_axe.c b/freebsd/sys/dev/usb/net/if_axe.c
index b77292ba..cf54e96e 100644
--- a/freebsd/sys/dev/usb/net/if_axe.c
+++ b/freebsd/sys/dev/usb/net/if_axe.c
@@ -504,7 +504,7 @@ axe_setmulti(struct usb_ether *ue)
rxmode &= ~AXE_RXCMD_ALLMULTI;
if_maddr_rlock(ifp);
- TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link)
+ CK_STAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link)
{
if (ifma->ifma_addr->sa_family != AF_LINK)
continue;
diff --git a/freebsd/sys/dev/usb/net/if_axge.c b/freebsd/sys/dev/usb/net/if_axge.c
index 575571e4..f8ed34ae 100644
--- a/freebsd/sys/dev/usb/net/if_axge.c
+++ b/freebsd/sys/dev/usb/net/if_axge.c
@@ -788,7 +788,7 @@ axge_rxfilter(struct usb_ether *ue)
rxmode |= RCR_ACPT_MCAST;
if_maddr_rlock(ifp);
- TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
+ CK_STAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
if (ifma->ifma_addr->sa_family != AF_LINK)
continue;
h = ether_crc32_be(LLADDR((struct sockaddr_dl *)
diff --git a/freebsd/sys/dev/usb/net/if_cue.c b/freebsd/sys/dev/usb/net/if_cue.c
index 63846a01..f184fa24 100644
--- a/freebsd/sys/dev/usb/net/if_cue.c
+++ b/freebsd/sys/dev/usb/net/if_cue.c
@@ -330,7 +330,7 @@ cue_setmulti(struct usb_ether *ue)
/* now program new ones */
if_maddr_rlock(ifp);
- TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link)
+ CK_STAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link)
{
if (ifma->ifma_addr->sa_family != AF_LINK)
continue;
diff --git a/freebsd/sys/dev/usb/net/if_kue.c b/freebsd/sys/dev/usb/net/if_kue.c
index 255a83bb..35fd3fcf 100644
--- a/freebsd/sys/dev/usb/net/if_kue.c
+++ b/freebsd/sys/dev/usb/net/if_kue.c
@@ -379,7 +379,7 @@ kue_setmulti(struct usb_ether *ue)
sc->sc_rxfilt &= ~KUE_RXFILT_ALLMULTI;
if_maddr_rlock(ifp);
- TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link)
+ CK_STAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link)
{
if (ifma->ifma_addr->sa_family != AF_LINK)
continue;
diff --git a/freebsd/sys/dev/usb/net/if_mos.c b/freebsd/sys/dev/usb/net/if_mos.c
index ad7bfcce..3dd0e5ef 100644
--- a/freebsd/sys/dev/usb/net/if_mos.c
+++ b/freebsd/sys/dev/usb/net/if_mos.c
@@ -608,7 +608,7 @@ mos_setmulti(struct usb_ether *ue)
/* get all new ones */
if_maddr_rlock(ifp);
- TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
+ CK_STAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
if (ifma->ifma_addr->sa_family != AF_LINK) {
allmulti = 1;
continue;
diff --git a/freebsd/sys/dev/usb/net/if_rue.c b/freebsd/sys/dev/usb/net/if_rue.c
index 7b062755..810a98c8 100644
--- a/freebsd/sys/dev/usb/net/if_rue.c
+++ b/freebsd/sys/dev/usb/net/if_rue.c
@@ -502,7 +502,7 @@ rue_setmulti(struct usb_ether *ue)
/* now program new ones */
if_maddr_rlock(ifp);
- TAILQ_FOREACH (ifma, &ifp->if_multiaddrs, ifma_link)
+ CK_STAILQ_FOREACH (ifma, &ifp->if_multiaddrs, ifma_link)
{
if (ifma->ifma_addr->sa_family != AF_LINK)
continue;
diff --git a/freebsd/sys/dev/usb/net/if_smsc.c b/freebsd/sys/dev/usb/net/if_smsc.c
index 88ecb618..87e181d8 100644
--- a/freebsd/sys/dev/usb/net/if_smsc.c
+++ b/freebsd/sys/dev/usb/net/if_smsc.c
@@ -454,7 +454,7 @@ smsc_miibus_readreg(device_t dev, int phy, int reg)
goto done;
}
- addr = (phy << 11) | (reg << 6) | SMSC_MII_READ;
+ addr = (phy << 11) | (reg << 6) | SMSC_MII_READ | SMSC_MII_BUSY;
smsc_write_reg(sc, SMSC_MII_ADDR, addr);
if (smsc_wait_for_bits(sc, SMSC_MII_ADDR, SMSC_MII_BUSY) != 0)
@@ -507,7 +507,7 @@ smsc_miibus_writereg(device_t dev, int phy, int reg, int val)
val = htole32(val);
smsc_write_reg(sc, SMSC_MII_DATA, val);
- addr = (phy << 11) | (reg << 6) | SMSC_MII_WRITE;
+ addr = (phy << 11) | (reg << 6) | SMSC_MII_WRITE | SMSC_MII_BUSY;
smsc_write_reg(sc, SMSC_MII_ADDR, addr);
if (smsc_wait_for_bits(sc, SMSC_MII_ADDR, SMSC_MII_BUSY) != 0)
@@ -716,14 +716,14 @@ smsc_setmulti(struct usb_ether *ue)
/* Take the lock of the mac address list before hashing each of them */
if_maddr_rlock(ifp);
- if (!TAILQ_EMPTY(&ifp->if_multiaddrs)) {
+ if (!CK_STAILQ_EMPTY(&ifp->if_multiaddrs)) {
/* We are filtering on a set of address so calculate hashes of each
* of the address and set the corresponding bits in the register.
*/
sc->sc_mac_csr |= SMSC_MAC_CSR_HPFILT;
sc->sc_mac_csr &= ~(SMSC_MAC_CSR_PRMS | SMSC_MAC_CSR_MCPAS);
- TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
+ CK_STAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
if (ifma->ifma_addr->sa_family != AF_LINK)
continue;
@@ -1308,7 +1308,7 @@ smsc_phy_init(struct smsc_softc *sc)
do {
uether_pause(&sc->sc_ue, hz / 100);
bmcr = smsc_miibus_readreg(sc->sc_ue.ue_dev, sc->sc_phyno, MII_BMCR);
- } while ((bmcr & MII_BMCR) && ((ticks - start_ticks) < max_ticks));
+ } while ((bmcr & BMCR_RESET) && ((ticks - start_ticks) < max_ticks));
if (((usb_ticks_t)(ticks - start_ticks)) >= max_ticks) {
smsc_err_printf(sc, "PHY reset timed-out");
diff --git a/freebsd/sys/dev/usb/net/if_udav.c b/freebsd/sys/dev/usb/net/if_udav.c
index 21019265..a4e683ac 100644
--- a/freebsd/sys/dev/usb/net/if_udav.c
+++ b/freebsd/sys/dev/usb/net/if_udav.c
@@ -524,7 +524,7 @@ udav_setmulti(struct usb_ether *ue)
/* now program new ones */
if_maddr_rlock(ifp);
- TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link)
+ CK_STAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link)
{
if (ifma->ifma_addr->sa_family != AF_LINK)
continue;
diff --git a/freebsd/sys/dev/usb/net/if_ure.c b/freebsd/sys/dev/usb/net/if_ure.c
index 0e45a6c9..8a88feae 100644
--- a/freebsd/sys/dev/usb/net/if_ure.c
+++ b/freebsd/sys/dev/usb/net/if_ure.c
@@ -797,7 +797,7 @@ ure_rxfilter(struct usb_ether *ue)
rxmode |= URE_RCR_AM;
if_maddr_rlock(ifp);
- TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
+ CK_STAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
if (ifma->ifma_addr->sa_family != AF_LINK)
continue;
h = ether_crc32_be(LLADDR((struct sockaddr_dl *)
diff --git a/freebsd/sys/dev/usb/net/usb_ethernet.c b/freebsd/sys/dev/usb/net/usb_ethernet.c
index 842e7987..9ce60eff 100644
--- a/freebsd/sys/dev/usb/net/usb_ethernet.c
+++ b/freebsd/sys/dev/usb/net/usb_ethernet.c
@@ -192,6 +192,17 @@ error:
return (error);
}
+void
+uether_ifattach_wait(struct usb_ether *ue)
+{
+
+ UE_LOCK(ue);
+ usb_proc_mwait(&ue->ue_tq,
+ &ue->ue_sync_task[0].hdr,
+ &ue->ue_sync_task[1].hdr);
+ UE_UNLOCK(ue);
+}
+
static void
ue_attach_post_task(struct usb_proc_msg *_task)
{
diff --git a/freebsd/sys/dev/usb/net/usb_ethernet.h b/freebsd/sys/dev/usb/net/usb_ethernet.h
index c7afc650..9839db16 100644
--- a/freebsd/sys/dev/usb/net/usb_ethernet.h
+++ b/freebsd/sys/dev/usb/net/usb_ethernet.h
@@ -113,6 +113,7 @@ struct ifnet *uether_getifp(struct usb_ether *);
struct mii_data *uether_getmii(struct usb_ether *);
void *uether_getsc(struct usb_ether *);
int uether_ifattach(struct usb_ether *);
+void uether_ifattach_wait(struct usb_ether *);
void uether_ifdetach(struct usb_ether *);
int uether_ifmedia_upd(struct ifnet *);
void uether_init(void *);
diff --git a/freebsd/sys/dev/usb/serial/uchcom.c b/freebsd/sys/dev/usb/serial/uchcom.c
index 1e741ccd..24cb8433 100644
--- a/freebsd/sys/dev/usb/serial/uchcom.c
+++ b/freebsd/sys/dev/usb/serial/uchcom.c
@@ -124,11 +124,11 @@ SYSCTL_INT(_hw_usb_uchcom, OID_AUTO, debug, CTLFLAG_RWTUN,
#define UCHCOM_REG_BPS_MOD 0x14
#define UCHCOM_REG_BPS_PAD 0x0F
#define UCHCOM_REG_BREAK1 0x05
-#define UCHCOM_REG_BREAK2 0x18
#define UCHCOM_REG_LCR1 0x18
#define UCHCOM_REG_LCR2 0x25
#define UCHCOM_VER_20 0x20
+#define UCHCOM_VER_30 0x30
#define UCHCOM_BASE_UNKNOWN 0
#define UCHCOM_BPS_MOD_BASE 20000000
@@ -137,12 +137,14 @@ SYSCTL_INT(_hw_usb_uchcom, OID_AUTO, debug, CTLFLAG_RWTUN,
#define UCHCOM_DTR_MASK 0x20
#define UCHCOM_RTS_MASK 0x40
-#define UCHCOM_BRK1_MASK 0x01
-#define UCHCOM_BRK2_MASK 0x40
+#define UCHCOM_BRK_MASK 0x01
#define UCHCOM_LCR1_MASK 0xAF
#define UCHCOM_LCR2_MASK 0x07
-#define UCHCOM_LCR1_PARENB 0x80
+#define UCHCOM_LCR1_RX 0x80
+#define UCHCOM_LCR1_TX 0x40
+#define UCHCOM_LCR1_PARENB 0x08
+#define UCHCOM_LCR1_CS8 0x03
#define UCHCOM_LCR2_PAREVEN 0x07
#define UCHCOM_LCR2_PARODD 0x06
#define UCHCOM_LCR2_PARMARK 0x05
@@ -324,13 +326,17 @@ uchcom_attach(device_t dev)
sc->sc_udev = uaa->device;
- switch (uaa->info.bcdDevice) {
- case UCHCOM_REV_CH340:
+ switch (uaa->info.idProduct) {
+ case USB_PRODUCT_WCH2_CH341SER:
device_printf(dev, "CH340 detected\n");
break;
- default:
+ case USB_PRODUCT_WCH2_CH341SER_2:
device_printf(dev, "CH341 detected\n");
break;
+ default:
+ device_printf(dev, "New CH340/CH341 product 0x%04x detected\n",
+ uaa->info.idProduct);
+ break;
}
iface_index = UCHCOM_IFACE_INDEX;
@@ -414,6 +420,8 @@ uchcom_ctrl_write(struct uchcom_softc *sc, uint8_t reqno,
USETW(req.wIndex, index);
USETW(req.wLength, 0);
+ DPRINTF("WR REQ 0x%02X VAL 0x%04X IDX 0x%04X\n",
+ reqno, value, index);
ucom_cfg_do_request(sc->sc_udev,
&sc->sc_ucom, &req, NULL, 0, 1000);
}
@@ -430,6 +438,8 @@ uchcom_ctrl_read(struct uchcom_softc *sc, uint8_t reqno,
USETW(req.wIndex, index);
USETW(req.wLength, buflen);
+ DPRINTF("RD REQ 0x%02X VAL 0x%04X IDX 0x%04X LEN %d\n",
+ reqno, value, index, buflen);
ucom_cfg_do_request(sc->sc_udev,
&sc->sc_ucom, &req, buf, USB_SHORT_XFER_OK, 1000);
}
@@ -504,6 +514,7 @@ static void
uchcom_update_version(struct uchcom_softc *sc)
{
uchcom_get_version(sc, &sc->sc_version);
+ DPRINTF("Chip version: 0x%02x\n", sc->sc_version);
}
static void
@@ -549,17 +560,17 @@ uchcom_cfg_set_break(struct ucom_softc *ucom, uint8_t onoff)
uint8_t brk1;
uint8_t brk2;
- uchcom_read_reg(sc, UCHCOM_REG_BREAK1, &brk1, UCHCOM_REG_BREAK2, &brk2);
+ uchcom_read_reg(sc, UCHCOM_REG_BREAK1, &brk1, UCHCOM_REG_LCR1, &brk2);
if (onoff) {
/* on - clear bits */
- brk1 &= ~UCHCOM_BRK1_MASK;
- brk2 &= ~UCHCOM_BRK2_MASK;
+ brk1 &= ~UCHCOM_BRK_MASK;
+ brk2 &= ~UCHCOM_LCR1_TX;
} else {
/* off - set bits */
- brk1 |= UCHCOM_BRK1_MASK;
- brk2 |= UCHCOM_BRK2_MASK;
+ brk1 |= UCHCOM_BRK_MASK;
+ brk2 |= UCHCOM_LCR1_TX;
}
- uchcom_write_reg(sc, UCHCOM_REG_BREAK1, brk1, UCHCOM_REG_BREAK2, brk2);
+ uchcom_write_reg(sc, UCHCOM_REG_BREAK1, brk1, UCHCOM_REG_LCR1, brk2);
}
static int
@@ -611,8 +622,12 @@ uchcom_set_baudrate(struct uchcom_softc *sc, uint32_t rate)
if (uchcom_calc_divider_settings(&dv, rate))
return;
+ /*
+ * According to linux code we need to set bit 7 of UCHCOM_REG_BPS_PRE,
+ * otherwise the chip will buffer data.
+ */
uchcom_write_reg(sc,
- UCHCOM_REG_BPS_PRE, dv.dv_prescaler,
+ UCHCOM_REG_BPS_PRE, dv.dv_prescaler | 0x80,
UCHCOM_REG_BPS_DIV, dv.dv_div);
uchcom_write_reg(sc,
UCHCOM_REG_BPS_MOD, dv.dv_mod,
@@ -678,6 +693,10 @@ uchcom_pre_param(struct ucom_softc *ucom, struct termios *t)
default:
return (EIO);
}
+ if ((t->c_cflag & CSTOPB) != 0)
+ return (EIO);
+ if ((t->c_cflag & PARENB) != 0)
+ return (EIO);
if (uchcom_calc_divider_settings(&dv, t->c_ospeed)) {
return (EIO);
@@ -690,11 +709,26 @@ uchcom_cfg_param(struct ucom_softc *ucom, struct termios *t)
{
struct uchcom_softc *sc = ucom->sc_parent;
- uchcom_get_version(sc, 0);
+ uchcom_get_version(sc, NULL);
uchcom_ctrl_write(sc, UCHCOM_REQ_RESET, 0, 0);
uchcom_set_baudrate(sc, t->c_ospeed);
- uchcom_read_reg(sc, 0x18, 0, 0x25, 0);
- uchcom_write_reg(sc, 0x18, 0x50, 0x25, 0x00);
+ if (sc->sc_version < UCHCOM_VER_30) {
+ uchcom_read_reg(sc, UCHCOM_REG_LCR1, NULL,
+ UCHCOM_REG_LCR2, NULL);
+ uchcom_write_reg(sc, UCHCOM_REG_LCR1, 0x50,
+ UCHCOM_REG_LCR2, 0x00);
+ } else {
+ /*
+ * Set up line control:
+ * - enable transmit and receive
+ * - set 8n1 mode
+ * To do: support other sizes, parity, stop bits.
+ */
+ uchcom_write_reg(sc,
+ UCHCOM_REG_LCR1,
+ UCHCOM_LCR1_RX | UCHCOM_LCR1_TX | UCHCOM_LCR1_CS8,
+ UCHCOM_REG_LCR2, 0x00);
+ }
uchcom_update_status(sc);
uchcom_ctrl_write(sc, UCHCOM_REQ_RESET, 0x501f, 0xd90a);
uchcom_set_baudrate(sc, t->c_ospeed);
diff --git a/freebsd/sys/dev/usb/serial/umodem.c b/freebsd/sys/dev/usb/serial/umodem.c
index ac1e35c8..76c7dfe2 100644
--- a/freebsd/sys/dev/usb/serial/umodem.c
+++ b/freebsd/sys/dev/usb/serial/umodem.c
@@ -459,6 +459,8 @@ umodem_attach(device_t dev)
mtx_unlock(&sc->sc_mtx);
}
+ ucom_set_usb_mode(&sc->sc_super_ucom, uaa->usb_mode);
+
error = ucom_attach(&sc->sc_super_ucom, &sc->sc_ucom, 1, sc,
&umodem_callback, &sc->sc_mtx);
if (error) {
diff --git a/freebsd/sys/dev/usb/serial/usb_serial.c b/freebsd/sys/dev/usb/serial/usb_serial.c
index 46a18d63..a3f9b5de 100644
--- a/freebsd/sys/dev/usb/serial/usb_serial.c
+++ b/freebsd/sys/dev/usb/serial/usb_serial.c
@@ -109,6 +109,12 @@ static int ucom_pps_mode;
SYSCTL_INT(_hw_usb_ucom, OID_AUTO, pps_mode, CTLFLAG_RWTUN,
&ucom_pps_mode, 0,
"pulse capture mode: 0/1/2=disabled/CTS/DCD; add 0x10 to invert");
+
+static int ucom_device_mode_console = 1;
+
+SYSCTL_INT(_hw_usb_ucom, OID_AUTO, device_mode_console, CTLFLAG_RW,
+ &ucom_device_mode_console, 0,
+ "set to 1 to mark terminals as consoles when in device mode");
#endif /* __rtems__ */
#ifdef USB_DEBUG
@@ -203,6 +209,7 @@ ucom_init(void *arg)
}
SYSINIT(ucom_init, SI_SUB_KLD - 1, SI_ORDER_ANY, ucom_init, NULL);
+#ifndef __rtems__
static void
ucom_uninit(void *arg)
{
@@ -218,6 +225,7 @@ ucom_uninit(void *arg)
mtx_destroy(&ucom_mtx);
}
SYSUNINIT(ucom_uninit, SI_SUB_KLD - 3, SI_ORDER_ANY, ucom_uninit, NULL);
+#endif /* __rtems__ */
/*
* Mark a unit number (the X in cuaUX) as in use.
@@ -294,7 +302,7 @@ ucom_attach(struct ucom_super_softc *ssc, struct ucom_softc *sc,
}
ssc->sc_subunits = subunits;
ssc->sc_flag = UCOM_FLAG_ATTACHED |
- UCOM_FLAG_FREE_UNIT;
+ UCOM_FLAG_FREE_UNIT | (ssc->sc_flag & UCOM_FLAG_DEVICE_MODE);
if (callback->ucom_free == NULL)
ssc->sc_flag |= UCOM_FLAG_WAIT_REFS;
@@ -394,6 +402,24 @@ ucom_drain_all(void *arg)
mtx_unlock(&ucom_mtx);
}
+static cn_probe_t ucom_cnprobe;
+static cn_init_t ucom_cninit;
+static cn_term_t ucom_cnterm;
+static cn_getc_t ucom_cngetc;
+static cn_putc_t ucom_cnputc;
+static cn_grab_t ucom_cngrab;
+static cn_ungrab_t ucom_cnungrab;
+
+const struct consdev_ops ucom_cnops = {
+ .cn_probe = ucom_cnprobe,
+ .cn_init = ucom_cninit,
+ .cn_term = ucom_cnterm,
+ .cn_getc = ucom_cngetc,
+ .cn_putc = ucom_cnputc,
+ .cn_grab = ucom_cngrab,
+ .cn_ungrab = ucom_cnungrab,
+};
+
static int
ucom_attach_tty(struct ucom_super_softc *ssc, struct ucom_softc *sc)
{
@@ -458,6 +484,26 @@ ucom_attach_tty(struct ucom_super_softc *ssc, struct ucom_softc *sc)
UCOM_MTX_UNLOCK(ucom_cons_softc);
}
+#ifndef __rtems__
+ if ((ssc->sc_flag & UCOM_FLAG_DEVICE_MODE) != 0 &&
+ ucom_device_mode_console > 0 &&
+ ucom_cons_softc == NULL) {
+ struct consdev *cp;
+
+ cp = malloc(sizeof(struct consdev), M_USBDEV,
+ M_WAITOK|M_ZERO);
+ cp->cn_ops = &ucom_cnops;
+ cp->cn_arg = NULL;
+ cp->cn_pri = CN_NORMAL;
+ strlcpy(cp->cn_name, "tty", sizeof(cp->cn_name));
+ strlcat(cp->cn_name, buf, sizeof(cp->cn_name));
+
+ sc->sc_consdev = cp;
+
+ cnadd(cp);
+ }
+#endif /* __rtems__ */
+
return (0);
}
@@ -468,6 +514,14 @@ ucom_detach_tty(struct ucom_super_softc *ssc, struct ucom_softc *sc)
DPRINTF("sc = %p, tp = %p\n", sc, sc->sc_tty);
+#ifndef __rtems__
+ if (sc->sc_consdev != NULL) {
+ cnremove(sc->sc_consdev);
+ free(sc->sc_consdev, M_USBDEV);
+ sc->sc_consdev = NULL;
+ }
+#endif /* __rtems__ */
+
if (sc->sc_flag & UCOM_FLAG_CONSOLE) {
UCOM_MTX_LOCK(ucom_cons_softc);
ucom_close(ucom_cons_softc->sc_tty);
@@ -541,6 +595,20 @@ ucom_set_pnpinfo_usb(struct ucom_super_softc *ssc, device_t dev)
}
}
+void
+ucom_set_usb_mode(struct ucom_super_softc *ssc, enum usb_hc_mode usb_mode)
+{
+
+ switch (usb_mode) {
+ case USB_MODE_DEVICE:
+ ssc->sc_flag |= UCOM_FLAG_DEVICE_MODE;
+ break;
+ default:
+ ssc->sc_flag &= ~UCOM_FLAG_DEVICE_MODE;
+ break;
+ }
+}
+
static void
ucom_queue_command(struct ucom_softc *sc,
usb_proc_callback_t *fn, struct termios *pt,
@@ -1547,14 +1615,6 @@ ucom_free(void *xsc)
mtx_unlock(&ucom_mtx);
}
-static cn_probe_t ucom_cnprobe;
-static cn_init_t ucom_cninit;
-static cn_term_t ucom_cnterm;
-static cn_getc_t ucom_cngetc;
-static cn_putc_t ucom_cnputc;
-static cn_grab_t ucom_cngrab;
-static cn_ungrab_t ucom_cnungrab;
-
CONSOLE_DRIVER(ucom);
static void
diff --git a/freebsd/sys/dev/usb/serial/usb_serial.h b/freebsd/sys/dev/usb/serial/usb_serial.h
index 9a5e043e..2bcc388d 100644
--- a/freebsd/sys/dev/usb/serial/usb_serial.h
+++ b/freebsd/sys/dev/usb/serial/usb_serial.h
@@ -165,6 +165,9 @@ struct ucom_softc {
const struct ucom_callback *sc_callback;
struct ucom_super_softc *sc_super;
struct tty *sc_tty;
+#ifndef __rtems__
+ struct consdev *sc_consdev;
+#endif /* __rtems__ */
struct mtx *sc_mtx;
void *sc_parent;
int sc_subunit;
@@ -183,6 +186,7 @@ struct ucom_softc {
#define UCOM_FLAG_FREE_UNIT 0x0200 /* set if we must free the unit */
#define UCOM_FLAG_INWAKEUP 0x0400 /* set if we are in the tsw_inwakeup callback */
#define UCOM_FLAG_LSRTXIDLE 0x0800 /* set if sc_lsr bits ULSR_TSRE+TXRDY work */
+#define UCOM_FLAG_DEVICE_MODE 0x1000 /* set if we're an USB device, not a host */
uint8_t sc_lsr;
uint8_t sc_msr;
uint8_t sc_mcr;
@@ -211,6 +215,7 @@ int ucom_attach(struct ucom_super_softc *,
const struct ucom_callback *callback, struct mtx *);
void ucom_detach(struct ucom_super_softc *, struct ucom_softc *);
void ucom_set_pnpinfo_usb(struct ucom_super_softc *, device_t);
+void ucom_set_usb_mode(struct ucom_super_softc *, enum usb_hc_mode);
void ucom_status_change(struct ucom_softc *);
uint8_t ucom_get_data(struct ucom_softc *, struct usb_page_cache *,
uint32_t, uint32_t, uint32_t *);
diff --git a/freebsd/sys/dev/usb/serial/uslcom.c b/freebsd/sys/dev/usb/serial/uslcom.c
index 45835b82..4128802d 100644
--- a/freebsd/sys/dev/usb/serial/uslcom.c
+++ b/freebsd/sys/dev/usb/serial/uslcom.c
@@ -66,7 +66,7 @@ SYSCTL_INT(_hw_usb_uslcom, OID_AUTO, debug, CTLFLAG_RWTUN,
&uslcom_debug, 0, "Debug level");
#endif
-#define USLCOM_BULK_BUF_SIZE 1024
+#define USLCOM_BULK_BUF_SIZE 1024
#define USLCOM_CONFIG_INDEX 0
/* Request types */
@@ -75,13 +75,13 @@ SYSCTL_INT(_hw_usb_uslcom, OID_AUTO, debug, CTLFLAG_RWTUN,
/* Request codes */
#define USLCOM_IFC_ENABLE 0x00
-#define USLCOM_SET_BAUDDIV 0x01
+#define USLCOM_SET_BAUDDIV 0x01
#define USLCOM_SET_LINE_CTL 0x03
#define USLCOM_SET_BREAK 0x05
#define USLCOM_SET_MHS 0x07
#define USLCOM_GET_MDMSTS 0x08
#define USLCOM_SET_FLOW 0x13
-#define USLCOM_SET_BAUDRATE 0x1e
+#define USLCOM_SET_BAUDRATE 0x1e
#define USLCOM_VENDOR_SPECIFIC 0xff
/* USLCOM_IFC_ENABLE values */
@@ -89,7 +89,7 @@ SYSCTL_INT(_hw_usb_uslcom, OID_AUTO, debug, CTLFLAG_RWTUN,
#define USLCOM_IFC_ENABLE_EN 0x01
/* USLCOM_SET_MHS/USLCOM_GET_MDMSTS values */
-#define USLCOM_MHS_DTR_ON 0x0001
+#define USLCOM_MHS_DTR_ON 0x0001
#define USLCOM_MHS_DTR_SET 0x0100
#define USLCOM_MHS_RTS_ON 0x0002
#define USLCOM_MHS_RTS_SET 0x0200
@@ -114,11 +114,11 @@ SYSCTL_INT(_hw_usb_uslcom, OID_AUTO, debug, CTLFLAG_RWTUN,
#define USLCOM_SET_BREAK_ON 0x01
/* USLCOM_SET_FLOW values - 1st word */
-#define USLCOM_FLOW_DTR_ON 0x00000001 /* DTR static active */
-#define USLCOM_FLOW_CTS_HS 0x00000008 /* CTS handshake */
+#define USLCOM_FLOW_DTR_ON 0x00000001 /* DTR static active */
+#define USLCOM_FLOW_CTS_HS 0x00000008 /* CTS handshake */
/* USLCOM_SET_FLOW values - 2nd word */
-#define USLCOM_FLOW_RTS_ON 0x00000040 /* RTS static active */
-#define USLCOM_FLOW_RTS_HS 0x00000080 /* RTS handshake */
+#define USLCOM_FLOW_RTS_ON 0x00000040 /* RTS static active */
+#define USLCOM_FLOW_RTS_HS 0x00000080 /* RTS handshake */
/* USLCOM_VENDOR_SPECIFIC values */
#define USLCOM_GET_PARTNUM 0x370B
@@ -148,10 +148,10 @@ struct uslcom_softc {
struct usb_device *sc_udev;
struct mtx sc_mtx;
- uint8_t sc_msr;
- uint8_t sc_lsr;
- uint8_t sc_iface_no;
- uint8_t sc_partnum;
+ uint8_t sc_msr;
+ uint8_t sc_lsr;
+ uint8_t sc_iface_no;
+ uint8_t sc_partnum;
};
static device_probe_t uslcom_probe;
@@ -163,18 +163,18 @@ static usb_callback_t uslcom_write_callback;
static usb_callback_t uslcom_read_callback;
static usb_callback_t uslcom_control_callback;
-static void uslcom_free(struct ucom_softc *);
-static void uslcom_open(struct ucom_softc *);
-static void uslcom_close(struct ucom_softc *);
+static void uslcom_free(struct ucom_softc *);
static uint8_t uslcom_get_partnum(struct uslcom_softc *);
-static void uslcom_set_dtr(struct ucom_softc *, uint8_t);
-static void uslcom_set_rts(struct ucom_softc *, uint8_t);
-static void uslcom_set_break(struct ucom_softc *, uint8_t);
+static void uslcom_cfg_open(struct ucom_softc *);
+static void uslcom_cfg_close(struct ucom_softc *);
+static void uslcom_cfg_set_dtr(struct ucom_softc *, uint8_t);
+static void uslcom_cfg_set_rts(struct ucom_softc *, uint8_t);
+static void uslcom_cfg_set_break(struct ucom_softc *, uint8_t);
+static void uslcom_cfg_param(struct ucom_softc *, struct termios *);
+static void uslcom_cfg_get_status(struct ucom_softc *, uint8_t *, uint8_t *);
static int uslcom_ioctl(struct ucom_softc *, uint32_t, caddr_t, int,
- struct thread *);
+ struct thread *);
static int uslcom_pre_param(struct ucom_softc *, struct termios *);
-static void uslcom_param(struct ucom_softc *, struct termios *);
-static void uslcom_get_status(struct ucom_softc *, uint8_t *, uint8_t *);
static void uslcom_start_read(struct ucom_softc *);
static void uslcom_stop_read(struct ucom_softc *);
static void uslcom_start_write(struct ucom_softc *);
@@ -182,7 +182,6 @@ static void uslcom_stop_write(struct ucom_softc *);
static void uslcom_poll(struct ucom_softc *ucom);
static const struct usb_config uslcom_config[USLCOM_N_TRANSFER] = {
-
[USLCOM_BULK_DT_WR] = {
.type = UE_BULK,
.endpoint = UE_ADDR_ANY,
@@ -212,15 +211,15 @@ static const struct usb_config uslcom_config[USLCOM_N_TRANSFER] = {
};
static struct ucom_callback uslcom_callback = {
- .ucom_cfg_open = &uslcom_open,
- .ucom_cfg_close = &uslcom_close,
- .ucom_cfg_get_status = &uslcom_get_status,
- .ucom_cfg_set_dtr = &uslcom_set_dtr,
- .ucom_cfg_set_rts = &uslcom_set_rts,
- .ucom_cfg_set_break = &uslcom_set_break,
- .ucom_ioctl = &uslcom_ioctl,
- .ucom_cfg_param = &uslcom_param,
+ .ucom_cfg_get_status = &uslcom_cfg_get_status,
+ .ucom_cfg_set_dtr = &uslcom_cfg_set_dtr,
+ .ucom_cfg_set_rts = &uslcom_cfg_set_rts,
+ .ucom_cfg_set_break = &uslcom_cfg_set_break,
+ .ucom_cfg_open = &uslcom_cfg_open,
+ .ucom_cfg_close = &uslcom_cfg_close,
+ .ucom_cfg_param = &uslcom_cfg_param,
.ucom_pre_param = &uslcom_pre_param,
+ .ucom_ioctl = &uslcom_ioctl,
.ucom_start_read = &uslcom_start_read,
.ucom_stop_read = &uslcom_stop_read,
.ucom_start_write = &uslcom_start_write,
@@ -501,7 +500,7 @@ uslcom_free(struct ucom_softc *ucom)
}
static void
-uslcom_open(struct ucom_softc *ucom)
+uslcom_cfg_open(struct ucom_softc *ucom)
{
struct uslcom_softc *sc = ucom->sc_parent;
struct usb_device_request req;
@@ -512,7 +511,7 @@ uslcom_open(struct ucom_softc *ucom)
USETW(req.wIndex, sc->sc_iface_no);
USETW(req.wLength, 0);
- if (ucom_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
+ if (ucom_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
&req, NULL, 0, 1000)) {
DPRINTF("UART enable failed (ignored)\n");
}
@@ -522,7 +521,7 @@ uslcom_open(struct ucom_softc *ucom)
}
static void
-uslcom_close(struct ucom_softc *ucom)
+uslcom_cfg_close(struct ucom_softc *ucom)
{
struct uslcom_softc *sc = ucom->sc_parent;
struct usb_device_request req;
@@ -536,7 +535,7 @@ uslcom_close(struct ucom_softc *ucom)
USETW(req.wIndex, sc->sc_iface_no);
USETW(req.wLength, 0);
- if (ucom_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
+ if (ucom_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
&req, NULL, 0, 1000)) {
DPRINTF("UART disable failed (ignored)\n");
}
@@ -565,13 +564,13 @@ uslcom_get_partnum(struct uslcom_softc *sc)
}
static void
-uslcom_set_dtr(struct ucom_softc *ucom, uint8_t onoff)
+uslcom_cfg_set_dtr(struct ucom_softc *ucom, uint8_t onoff)
{
- struct uslcom_softc *sc = ucom->sc_parent;
+ struct uslcom_softc *sc = ucom->sc_parent;
struct usb_device_request req;
uint16_t ctl;
- DPRINTF("onoff = %d\n", onoff);
+ DPRINTF("onoff = %d\n", onoff);
ctl = onoff ? USLCOM_MHS_DTR_ON : 0;
ctl |= USLCOM_MHS_DTR_SET;
@@ -582,20 +581,20 @@ uslcom_set_dtr(struct ucom_softc *ucom, uint8_t onoff)
USETW(req.wIndex, sc->sc_iface_no);
USETW(req.wLength, 0);
- if (ucom_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
+ if (ucom_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
&req, NULL, 0, 1000)) {
DPRINTF("Setting DTR failed (ignored)\n");
}
}
static void
-uslcom_set_rts(struct ucom_softc *ucom, uint8_t onoff)
+uslcom_cfg_set_rts(struct ucom_softc *ucom, uint8_t onoff)
{
- struct uslcom_softc *sc = ucom->sc_parent;
+ struct uslcom_softc *sc = ucom->sc_parent;
struct usb_device_request req;
uint16_t ctl;
- DPRINTF("onoff = %d\n", onoff);
+ DPRINTF("onoff = %d\n", onoff);
ctl = onoff ? USLCOM_MHS_RTS_ON : 0;
ctl |= USLCOM_MHS_RTS_SET;
@@ -606,7 +605,7 @@ uslcom_set_rts(struct ucom_softc *ucom, uint8_t onoff)
USETW(req.wIndex, sc->sc_iface_no);
USETW(req.wLength, 0);
- if (ucom_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
+ if (ucom_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
&req, NULL, 0, 1000)) {
DPRINTF("Setting DTR failed (ignored)\n");
}
@@ -615,13 +614,28 @@ uslcom_set_rts(struct ucom_softc *ucom, uint8_t onoff)
static int
uslcom_pre_param(struct ucom_softc *ucom, struct termios *t)
{
- if (t->c_ospeed <= 0 || t->c_ospeed > 921600)
+ struct uslcom_softc *sc = ucom->sc_parent;
+ uint32_t maxspeed;
+
+ switch (sc->sc_partnum) {
+ case USLCOM_PARTNUM_CP2104:
+ case USLCOM_PARTNUM_CP2105:
+ maxspeed = 2000000;
+ break;
+ case USLCOM_PARTNUM_CP2101:
+ case USLCOM_PARTNUM_CP2102:
+ case USLCOM_PARTNUM_CP2103:
+ default:
+ maxspeed = 921600;
+ break;
+ }
+ if (t->c_ospeed <= 0 || t->c_ospeed > maxspeed)
return (EINVAL);
return (0);
}
static void
-uslcom_param(struct ucom_softc *ucom, struct termios *t)
+uslcom_cfg_param(struct ucom_softc *ucom, struct termios *t)
{
struct uslcom_softc *sc = ucom->sc_parent;
struct usb_device_request req;
@@ -637,9 +651,9 @@ uslcom_param(struct ucom_softc *ucom, struct termios *t)
USETW(req.wIndex, sc->sc_iface_no);
USETW(req.wLength, sizeof(baudrate));
- if (ucom_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
+ if (ucom_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
&req, &baudrate, 0, 1000)) {
- DPRINTF("Set baudrate failed (ignored)\n");
+ printf("Set baudrate failed (ignored)\n");
}
if (t->c_cflag & CSTOPB)
@@ -674,11 +688,11 @@ uslcom_param(struct ucom_softc *ucom, struct termios *t)
USETW(req.wIndex, sc->sc_iface_no);
USETW(req.wLength, 0);
- if (ucom_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
+ if (ucom_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
&req, NULL, 0, 1000)) {
DPRINTF("Set format failed (ignored)\n");
}
-
+
if (t->c_cflag & CRTSCTS) {
flowctrl[0] = htole32(USLCOM_FLOW_DTR_ON | USLCOM_FLOW_CTS_HS);
flowctrl[1] = htole32(USLCOM_FLOW_RTS_HS);
@@ -694,14 +708,14 @@ uslcom_param(struct ucom_softc *ucom, struct termios *t)
USETW(req.wIndex, sc->sc_iface_no);
USETW(req.wLength, sizeof(flowctrl));
- if (ucom_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
+ if (ucom_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
&req, flowctrl, 0, 1000)) {
DPRINTF("Set flowcontrol failed (ignored)\n");
}
}
static void
-uslcom_get_status(struct ucom_softc *ucom, uint8_t *lsr, uint8_t *msr)
+uslcom_cfg_get_status(struct ucom_softc *ucom, uint8_t *lsr, uint8_t *msr)
{
struct uslcom_softc *sc = ucom->sc_parent;
@@ -713,9 +727,9 @@ uslcom_get_status(struct ucom_softc *ucom, uint8_t *lsr, uint8_t *msr)
}
static void
-uslcom_set_break(struct ucom_softc *ucom, uint8_t onoff)
+uslcom_cfg_set_break(struct ucom_softc *ucom, uint8_t onoff)
{
- struct uslcom_softc *sc = ucom->sc_parent;
+ struct uslcom_softc *sc = ucom->sc_parent;
struct usb_device_request req;
uint16_t brk = onoff ? USLCOM_SET_BREAK_ON : USLCOM_SET_BREAK_OFF;
@@ -725,7 +739,7 @@ uslcom_set_break(struct ucom_softc *ucom, uint8_t onoff)
USETW(req.wIndex, sc->sc_iface_no);
USETW(req.wLength, 0);
- if (ucom_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
+ if (ucom_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
&req, NULL, 0, 1000)) {
DPRINTF("Set BREAK failed (ignored)\n");
}
@@ -754,7 +768,7 @@ uslcom_ioctl(struct ucom_softc *ucom, uint32_t cmd, caddr_t data,
USETW(req.wIndex, sc->sc_iface_no);
USETW(req.wLength, sizeof(latch));
- if (ucom_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
+ if (ucom_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
&req, &latch, 0, 1000)) {
DPRINTF("Get LATCH failed\n");
error = EIO;
@@ -773,7 +787,7 @@ uslcom_ioctl(struct ucom_softc *ucom, uint32_t cmd, caddr_t data,
USETW(req.wIndex, (*(int *)data));
USETW(req.wLength, 0);
- if (ucom_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
+ if (ucom_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
&req, NULL, 0, 1000)) {
DPRINTF("Set LATCH failed\n");
error = EIO;
@@ -888,7 +902,7 @@ uslcom_control_callback(struct usb_xfer *xfer, usb_error_t error)
USETW(req.wValue, 0);
USETW(req.wIndex, sc->sc_iface_no);
USETW(req.wLength, sizeof(buf));
-
+
usbd_xfer_set_frames(xfer, 2);
usbd_xfer_set_frame_len(xfer, 0, sizeof(req));
usbd_xfer_set_frame_len(xfer, 1, sizeof(buf));
diff --git a/freebsd/sys/dev/usb/usb_device.c b/freebsd/sys/dev/usb/usb_device.c
index 5f1cf409..5d6b9d0f 100644
--- a/freebsd/sys/dev/usb/usb_device.c
+++ b/freebsd/sys/dev/usb/usb_device.c
@@ -120,7 +120,7 @@ static void usb_cdev_free(struct usb_device *);
#ifdef USB_TEMPLATE
int usb_template = USB_TEMPLATE;
#else
-int usb_template;
+int usb_template = -1;
#endif
#ifndef __rtems__
diff --git a/freebsd/sys/dev/usb/usb_ioctl.h b/freebsd/sys/dev/usb/usb_ioctl.h
index 7cf90649..fcd31e31 100644
--- a/freebsd/sys/dev/usb/usb_ioctl.h
+++ b/freebsd/sys/dev/usb/usb_ioctl.h
@@ -69,6 +69,7 @@ enum {
USB_TEMP_PHONE, /* USB Phone */
USB_TEMP_SERIALNET, /* USB CDC Ethernet and Modem */
USB_TEMP_MIDI, /* USB MIDI */
+ USB_TEMP_MULTI, /* USB Ethernet, serial, and storage */
USB_TEMP_MAX,
};
diff --git a/freebsd/sys/dev/usb/usb_request.c b/freebsd/sys/dev/usb/usb_request.c
index 6be241c2..cb69ce0e 100644
--- a/freebsd/sys/dev/usb/usb_request.c
+++ b/freebsd/sys/dev/usb/usb_request.c
@@ -1157,7 +1157,11 @@ usbd_req_get_string_any(struct usb_device *udev, struct mtx *mtx, char *buf,
*s == '+' ||
*s == ' ' ||
*s == '.' ||
- *s == ',') {
+ *s == ',' ||
+ *s == ':' ||
+ *s == '/' ||
+ *s == '(' ||
+ *s == ')') {
/* allowed */
s++;
}
diff --git a/freebsd/sys/dev/usb/wlan/if_rsu.c b/freebsd/sys/dev/usb/wlan/if_rsu.c
index 179de4e5..1cb504cc 100644
--- a/freebsd/sys/dev/usb/wlan/if_rsu.c
+++ b/freebsd/sys/dev/usb/wlan/if_rsu.c
@@ -890,7 +890,7 @@ rsu_set_multi(struct rsu_softc *sc)
TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
ifp = vap->iv_ifp;
if_maddr_rlock(ifp);
- TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
+ CK_STAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
caddr_t dl;
uint8_t pos;
diff --git a/freebsd/sys/dev/usb/wlan/if_zyd.c b/freebsd/sys/dev/usb/wlan/if_zyd.c
index dee03bdd..1835b58b 100644
--- a/freebsd/sys/dev/usb/wlan/if_zyd.c
+++ b/freebsd/sys/dev/usb/wlan/if_zyd.c
@@ -2002,7 +2002,7 @@ zyd_set_multi(struct zyd_softc *sc)
TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
ifp = vap->iv_ifp;
if_maddr_rlock(ifp);
- TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
+ CK_STAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
if (ifma->ifma_addr->sa_family != AF_LINK)
continue;
v = ((uint8_t *)LLADDR((struct sockaddr_dl *)