diff options
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/alc/if_alc.c | 7 | ||||
-rw-r--r-- | sys/dev/alc/if_alcreg.h | 1 | ||||
-rw-r--r-- | sys/dev/e1000/if_em.c | 2 | ||||
-rw-r--r-- | sys/dev/hyperv/include/hyperv.h | 12 | ||||
-rw-r--r-- | sys/dev/hyperv/netvsc/hn_nvs.c | 14 | ||||
-rw-r--r-- | sys/dev/hyperv/netvsc/hn_nvs.h | 1 | ||||
-rw-r--r-- | sys/dev/hyperv/netvsc/if_hn.c | 202 | ||||
-rw-r--r-- | sys/dev/hyperv/netvsc/if_hnreg.h | 11 | ||||
-rw-r--r-- | sys/dev/hyperv/netvsc/if_hnvar.h | 7 | ||||
-rw-r--r-- | sys/dev/hyperv/utilities/vmbus_timesync.c | 5 | ||||
-rw-r--r-- | sys/dev/hyperv/vmbus/amd64/hyperv_machdep.c | 18 | ||||
-rw-r--r-- | sys/dev/hyperv/vmbus/hyperv.c | 15 | ||||
-rw-r--r-- | sys/dev/hyperv/vmbus/vmbus_et.c | 17 | ||||
-rw-r--r-- | sys/dev/isp/isp.c | 15 | ||||
-rw-r--r-- | sys/dev/nand/nand_geom.c | 2 | ||||
-rw-r--r-- | sys/dev/pci/pci.c | 5 | ||||
-rw-r--r-- | sys/dev/ppbus/vpo.c | 2 |
17 files changed, 283 insertions, 53 deletions
diff --git a/sys/dev/alc/if_alc.c b/sys/dev/alc/if_alc.c index 76e4614..e789a1d 100644 --- a/sys/dev/alc/if_alc.c +++ b/sys/dev/alc/if_alc.c @@ -122,6 +122,8 @@ static struct alc_ident alc_ident_table[] = { "Killer E2200 Gigabit Ethernet" }, { VENDORID_ATHEROS, DEVICEID_ATHEROS_E2400, 9 * 1024, "Killer E2400 Gigabit Ethernet" }, + { VENDORID_ATHEROS, DEVICEID_ATHEROS_E2500, 9 * 1024, + "Killer E2500 Gigabit Ethernet" }, { 0, 0, 0, NULL} }; @@ -1082,6 +1084,7 @@ alc_phy_down(struct alc_softc *sc) case DEVICEID_ATHEROS_AR8161: case DEVICEID_ATHEROS_E2200: case DEVICEID_ATHEROS_E2400: + case DEVICEID_ATHEROS_E2500: case DEVICEID_ATHEROS_AR8162: case DEVICEID_ATHEROS_AR8171: case DEVICEID_ATHEROS_AR8172: @@ -1401,6 +1404,7 @@ alc_attach(device_t dev) switch (sc->alc_ident->deviceid) { case DEVICEID_ATHEROS_E2200: case DEVICEID_ATHEROS_E2400: + case DEVICEID_ATHEROS_E2500: sc->alc_flags |= ALC_FLAG_E2X00; /* FALLTHROUGH */ case DEVICEID_ATHEROS_AR8161: @@ -1479,7 +1483,8 @@ alc_attach(device_t dev) if (alc_dma_burst[sc->alc_dma_wr_burst] > 1024) sc->alc_dma_wr_burst = 3; /* - * Force maximum payload size to 128 bytes for E2200/E2400. + * Force maximum payload size to 128 bytes for + * E2200/E2400/E2500. * Otherwise it triggers DMA write error. */ if ((sc->alc_flags & ALC_FLAG_E2X00) != 0) diff --git a/sys/dev/alc/if_alcreg.h b/sys/dev/alc/if_alcreg.h index ae63084..29d877d 100644 --- a/sys/dev/alc/if_alcreg.h +++ b/sys/dev/alc/if_alcreg.h @@ -50,6 +50,7 @@ #define DEVICEID_ATHEROS_AR8172 0x10A0 #define DEVICEID_ATHEROS_E2200 0xE091 #define DEVICEID_ATHEROS_E2400 0xE0A1 +#define DEVICEID_ATHEROS_E2500 0xE0B1 #define ATHEROS_AR8152_B_V10 0xC0 #define ATHEROS_AR8152_B_V11 0xC1 diff --git a/sys/dev/e1000/if_em.c b/sys/dev/e1000/if_em.c index 6b6b791..e9ab2f6 100644 --- a/sys/dev/e1000/if_em.c +++ b/sys/dev/e1000/if_em.c @@ -5156,7 +5156,7 @@ em_enable_intr(struct adapter *adapter) u32 ims_mask = IMS_ENABLE_MASK; if (hw->mac.type == e1000_82574) { - E1000_WRITE_REG(hw, EM_EIAC, adapter->ims); + E1000_WRITE_REG(hw, EM_EIAC, EM_MSIX_MASK); ims_mask |= adapter->ims; } E1000_WRITE_REG(hw, E1000_IMS, ims_mask); diff --git a/sys/dev/hyperv/include/hyperv.h b/sys/dev/hyperv/include/hyperv.h index 0eda9f0..f0161fc 100644 --- a/sys/dev/hyperv/include/hyperv.h +++ b/sys/dev/hyperv/include/hyperv.h @@ -79,9 +79,17 @@ struct hyperv_guid { #define HYPERV_GUID_STRLEN 40 -int hyperv_guid2str(const struct hyperv_guid *, char *, size_t); +typedef uint64_t (*hyperv_tc64_t)(void); -extern u_int hyperv_features; /* CPUID_HV_MSR_ */ +int hyperv_guid2str(const struct hyperv_guid *, char *, + size_t); + +/* + * hyperv_tc64 could be NULL, if there were no suitable Hyper-V + * specific timecounter. + */ +extern hyperv_tc64_t hyperv_tc64; +extern u_int hyperv_features; /* CPUID_HV_MSR_ */ #endif /* _KERNEL */ diff --git a/sys/dev/hyperv/netvsc/hn_nvs.c b/sys/dev/hyperv/netvsc/hn_nvs.c index aa61a33..b4e9b1a 100644 --- a/sys/dev/hyperv/netvsc/hn_nvs.c +++ b/sys/dev/hyperv/netvsc/hn_nvs.c @@ -500,6 +500,8 @@ hn_nvs_conf_ndis(struct hn_softc *sc, int mtu) conf.nvs_type = HN_NVS_TYPE_NDIS_CONF; conf.nvs_mtu = mtu; conf.nvs_caps = HN_NVS_NDIS_CONF_VLAN; + if (sc->hn_nvs_ver >= HN_NVS_VERSION_5) + conf.nvs_caps |= HN_NVS_NDIS_CONF_SRIOV; /* NOTE: No response. */ error = hn_nvs_req_send(sc, &conf, sizeof(conf)); @@ -719,3 +721,15 @@ hn_nvs_send_rndis_ctrl(struct vmbus_channel *chan, return hn_nvs_send_rndis_sglist(chan, HN_NVS_RNDIS_MTYPE_CTRL, sndc, gpa, gpa_cnt); } + +void +hn_nvs_set_datapath(struct hn_softc *sc, uint32_t path) +{ + struct hn_nvs_datapath dp; + + memset(&dp, 0, sizeof(dp)); + dp.nvs_type = HN_NVS_TYPE_SET_DATAPATH; + dp.nvs_active_path = path; + + hn_nvs_req_send(sc, &dp, sizeof(dp)); +} diff --git a/sys/dev/hyperv/netvsc/hn_nvs.h b/sys/dev/hyperv/netvsc/hn_nvs.h index 49b03e0..f716abf 100644 --- a/sys/dev/hyperv/netvsc/hn_nvs.h +++ b/sys/dev/hyperv/netvsc/hn_nvs.h @@ -100,6 +100,7 @@ void hn_nvs_sent_xact(struct hn_nvs_sendctx *sndc, int hn_nvs_send_rndis_ctrl(struct vmbus_channel *chan, struct hn_nvs_sendctx *sndc, struct vmbus_gpa *gpa, int gpa_cnt); +void hn_nvs_set_datapath(struct hn_softc *sc, uint32_t path); extern struct hn_nvs_sendctx hn_nvs_sendctx_none; diff --git a/sys/dev/hyperv/netvsc/if_hn.c b/sys/dev/hyperv/netvsc/if_hn.c index 8750ab0..8e99eef 100644 --- a/sys/dev/hyperv/netvsc/if_hn.c +++ b/sys/dev/hyperv/netvsc/if_hn.c @@ -77,6 +77,7 @@ __FBSDID("$FreeBSD$"); #include <sys/systm.h> #include <sys/taskqueue.h> #include <sys/buf_ring.h> +#include <sys/eventhandler.h> #include <machine/atomic.h> #include <machine/in_cksum.h> @@ -85,6 +86,7 @@ __FBSDID("$FreeBSD$"); #include <net/ethernet.h> #include <net/if.h> #include <net/if_arp.h> +#include <net/if_dl.h> #include <net/if_media.h> #include <net/if_types.h> #include <net/if_var.h> @@ -211,6 +213,11 @@ struct hn_rxinfo { uint32_t hash_value; }; +struct hn_update_vf { + struct hn_rx_ring *rxr; + struct ifnet *vf; +}; + #define HN_RXINFO_VLAN 0x0001 #define HN_RXINFO_CSUM 0x0002 #define HN_RXINFO_HASHINF 0x0004 @@ -287,8 +294,9 @@ static int hn_txagg_pkts_sysctl(SYSCTL_HANDLER_ARGS); static int hn_txagg_pktmax_sysctl(SYSCTL_HANDLER_ARGS); static int hn_txagg_align_sysctl(SYSCTL_HANDLER_ARGS); static int hn_polling_sysctl(SYSCTL_HANDLER_ARGS); +static int hn_vf_sysctl(SYSCTL_HANDLER_ARGS); -static void hn_stop(struct hn_softc *); +static void hn_stop(struct hn_softc *, bool); static void hn_init_locked(struct hn_softc *); static int hn_chan_attach(struct hn_softc *, struct vmbus_channel *); @@ -696,7 +704,8 @@ hn_rxfilter_config(struct hn_softc *sc) HN_LOCK_ASSERT(sc); - if (ifp->if_flags & IFF_PROMISC) { + if ((ifp->if_flags & IFF_PROMISC) || + (sc->hn_flags & HN_FLAG_VF)) { filter = NDIS_PACKET_TYPE_PROMISCUOUS; } else { filter = NDIS_PACKET_TYPE_DIRECTED; @@ -883,6 +892,122 @@ hn_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr) ifmr->ifm_active |= IFM_10G_T | IFM_FDX; } +static void +hn_update_vf_task(void *arg, int pending __unused) +{ + struct hn_update_vf *uv = arg; + + uv->rxr->hn_vf = uv->vf; +} + +static void +hn_update_vf(struct hn_softc *sc, struct ifnet *vf) +{ + struct hn_rx_ring *rxr; + struct hn_update_vf uv; + struct task task; + int i; + + HN_LOCK_ASSERT(sc); + + TASK_INIT(&task, 0, hn_update_vf_task, &uv); + + for (i = 0; i < sc->hn_rx_ring_cnt; ++i) { + rxr = &sc->hn_rx_ring[i]; + + if (i < sc->hn_rx_ring_inuse) { + uv.rxr = rxr; + uv.vf = vf; + vmbus_chan_run_task(rxr->hn_chan, &task); + } else { + rxr->hn_vf = vf; + } + } +} + +static void +hn_set_vf(struct hn_softc *sc, struct ifnet *ifp, bool vf) +{ + struct ifnet *hn_ifp; + + HN_LOCK(sc); + + if (!(sc->hn_flags & HN_FLAG_SYNTH_ATTACHED)) + goto out; + + hn_ifp = sc->hn_ifp; + + if (ifp == hn_ifp) + goto out; + + if (ifp->if_alloctype != IFT_ETHER) + goto out; + + /* Ignore lagg/vlan interfaces */ + if (strcmp(ifp->if_dname, "lagg") == 0 || + strcmp(ifp->if_dname, "vlan") == 0) + goto out; + + if (bcmp(IF_LLADDR(ifp), IF_LLADDR(hn_ifp), ETHER_ADDR_LEN) != 0) + goto out; + + /* Now we're sure 'ifp' is a real VF device. */ + if (vf) { + if (sc->hn_flags & HN_FLAG_VF) + goto out; + + sc->hn_flags |= HN_FLAG_VF; + hn_rxfilter_config(sc); + } else { + if (!(sc->hn_flags & HN_FLAG_VF)) + goto out; + + sc->hn_flags &= ~HN_FLAG_VF; + if (sc->hn_ifp->if_drv_flags & IFF_DRV_RUNNING) + hn_rxfilter_config(sc); + else + hn_set_rxfilter(sc, NDIS_PACKET_TYPE_NONE); + } + + hn_nvs_set_datapath(sc, + vf ? HN_NVS_DATAPATH_VF : HN_NVS_DATAPATH_SYNTHETIC); + + hn_update_vf(sc, vf ? ifp : NULL); + + if (vf) { + hn_suspend_mgmt(sc); + sc->hn_link_flags &= + ~(HN_LINK_FLAG_LINKUP | HN_LINK_FLAG_NETCHG); + if_link_state_change(sc->hn_ifp, LINK_STATE_DOWN); + } else { + hn_resume_mgmt(sc); + } + + devctl_notify("HYPERV_NIC_VF", if_name(hn_ifp), + vf ? "VF_UP" : "VF_DOWN", NULL); + + if (bootverbose) + if_printf(hn_ifp, "Data path is switched %s %s\n", + vf ? "to" : "from", if_name(ifp)); +out: + HN_UNLOCK(sc); +} + +static void +hn_ifnet_event(void *arg, struct ifnet *ifp, int event) +{ + if (event != IFNET_EVENT_UP && event != IFNET_EVENT_DOWN) + return; + + hn_set_vf(arg, ifp, event == IFNET_EVENT_UP); +} + +static void +hn_ifaddr_event(void *arg, struct ifnet *ifp) +{ + hn_set_vf(arg, ifp, ifp->if_flags & IFF_UP); +} + /* {F8615163-DF3E-46c5-913F-F2D2F965ED0E} */ static const struct hyperv_guid g_net_vsc_device_type = { .hv_guid = {0x63, 0x51, 0x61, 0xF8, 0x3E, 0xDF, 0xc5, 0x46, @@ -1111,6 +1236,9 @@ hn_attach(device_t dev) CTLTYPE_UINT | CTLFLAG_RW | CTLFLAG_MPSAFE, sc, 0, hn_polling_sysctl, "I", "Polling frequency: [100,1000000], 0 disable polling"); + SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "vf", + CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, sc, 0, + hn_vf_sysctl, "A", "Virtual Function's name"); /* * Setup the ifmedia, which has been initialized earlier. @@ -1204,6 +1332,12 @@ hn_attach(device_t dev) sc->hn_mgmt_taskq = sc->hn_mgmt_taskq0; hn_update_link_status(sc); + sc->hn_ifnet_evthand = EVENTHANDLER_REGISTER(ifnet_event, + hn_ifnet_event, sc, EVENTHANDLER_PRI_ANY); + + sc->hn_ifaddr_evthand = EVENTHANDLER_REGISTER(ifaddr_event, + hn_ifaddr_event, sc, EVENTHANDLER_PRI_ANY); + return (0); failed: if (sc->hn_flags & HN_FLAG_SYNTH_ATTACHED) @@ -1218,6 +1352,11 @@ hn_detach(device_t dev) struct hn_softc *sc = device_get_softc(dev); struct ifnet *ifp = sc->hn_ifp; + if (sc->hn_ifaddr_evthand != NULL) + EVENTHANDLER_DEREGISTER(ifaddr_event, sc->hn_ifaddr_evthand); + if (sc->hn_ifnet_evthand != NULL) + EVENTHANDLER_DEREGISTER(ifnet_event, sc->hn_ifnet_evthand); + if (sc->hn_xact != NULL && vmbus_chan_is_revoked(sc->hn_prichan)) { /* * In case that the vmbus missed the orphan handler @@ -1230,7 +1369,7 @@ hn_detach(device_t dev) HN_LOCK(sc); if (sc->hn_flags & HN_FLAG_SYNTH_ATTACHED) { if (ifp->if_drv_flags & IFF_DRV_RUNNING) - hn_stop(sc); + hn_stop(sc, true); /* * NOTE: * hn_stop() only suspends data, so managment @@ -2113,20 +2252,15 @@ static int hn_rxpkt(struct hn_rx_ring *rxr, const void *data, int dlen, const struct hn_rxinfo *info) { - struct ifnet *ifp = rxr->hn_ifp; + struct ifnet *ifp; struct mbuf *m_new; int size, do_lro = 0, do_csum = 1; int hash_type = M_HASHTYPE_OPAQUE; - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) - return (0); + /* If the VF is active, inject the packet through the VF */ + ifp = rxr->hn_vf ? rxr->hn_vf : rxr->hn_ifp; - /* - * Bail out if packet contains more data than configured MTU. - */ - if (dlen > (ifp->if_mtu + ETHER_HDR_LEN)) { - return (0); - } else if (dlen <= MHLEN) { + if (dlen <= MHLEN) { m_new = m_gethdr(M_NOWAIT, MT_DATA); if (m_new == NULL) { if_inc_counter(ifp, IFCOUNTER_IQDROPS, 1); @@ -2434,7 +2568,7 @@ hn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) } } else { if (ifp->if_drv_flags & IFF_DRV_RUNNING) - hn_stop(sc); + hn_stop(sc, false); } sc->hn_if_flags = ifp->if_flags; @@ -2524,7 +2658,7 @@ hn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) } static void -hn_stop(struct hn_softc *sc) +hn_stop(struct hn_softc *sc, bool detaching) { struct ifnet *ifp = sc->hn_ifp; int i; @@ -2545,6 +2679,13 @@ hn_stop(struct hn_softc *sc) atomic_clear_int(&ifp->if_drv_flags, IFF_DRV_OACTIVE); for (i = 0; i < sc->hn_tx_ring_inuse; ++i) sc->hn_tx_ring[i].hn_oactive = 0; + + /* + * If the VF is active, make sure the filter is not 0, even if + * the synthetic NIC is down. + */ + if (!detaching && (sc->hn_flags & HN_FLAG_VF)) + hn_rxfilter_config(sc); } static void @@ -3071,6 +3212,22 @@ hn_rss_hash_sysctl(SYSCTL_HANDLER_ARGS) } static int +hn_vf_sysctl(SYSCTL_HANDLER_ARGS) +{ + struct hn_softc *sc = arg1; + char vf_name[128]; + struct ifnet *vf; + + HN_LOCK(sc); + vf_name[0] = '\0'; + vf = sc->hn_rx_ring[0].hn_vf; + if (vf != NULL) + snprintf(vf_name, sizeof(vf_name), "%s", if_name(vf)); + HN_UNLOCK(sc); + return sysctl_handle_string(oidp, vf_name, sizeof(vf_name), req); +} + +static int hn_check_iplen(const struct mbuf *m, int hoff) { const struct ip *ip; @@ -4297,6 +4454,7 @@ hn_chan_attach(struct hn_softc *sc, struct vmbus_channel *chan) KASSERT((rxr->hn_rx_flags & HN_RX_FLAG_ATTACHED) == 0, ("RX ring %d already attached", idx)); rxr->hn_rx_flags |= HN_RX_FLAG_ATTACHED; + rxr->hn_chan = chan; if (bootverbose) { if_printf(sc->hn_ifp, "link RX ring %d to chan%u\n", @@ -4855,7 +5013,8 @@ hn_suspend(struct hn_softc *sc) /* Disable polling. */ hn_polling(sc, 0); - if (sc->hn_ifp->if_drv_flags & IFF_DRV_RUNNING) + if ((sc->hn_ifp->if_drv_flags & IFF_DRV_RUNNING) || + (sc->hn_flags & HN_FLAG_VF)) hn_suspend_data(sc); hn_suspend_mgmt(sc); } @@ -4944,9 +5103,18 @@ static void hn_resume(struct hn_softc *sc) { - if (sc->hn_ifp->if_drv_flags & IFF_DRV_RUNNING) + if ((sc->hn_ifp->if_drv_flags & IFF_DRV_RUNNING) || + (sc->hn_flags & HN_FLAG_VF)) hn_resume_data(sc); - hn_resume_mgmt(sc); + + /* + * When the VF is activated, the synthetic interface is changed + * to DOWN in hn_set_vf(). Here, if the VF is still active, we + * don't call hn_resume_mgmt() until the VF is deactivated in + * hn_set_vf(). + */ + if (!(sc->hn_flags & HN_FLAG_VF)) + hn_resume_mgmt(sc); /* * Re-enable polling if this interface is running and diff --git a/sys/dev/hyperv/netvsc/if_hnreg.h b/sys/dev/hyperv/netvsc/if_hnreg.h index a3b2b8b..a964b4f 100644 --- a/sys/dev/hyperv/netvsc/if_hnreg.h +++ b/sys/dev/hyperv/netvsc/if_hnreg.h @@ -133,6 +133,17 @@ struct hn_nvs_ndis_init { } __packed; CTASSERT(sizeof(struct hn_nvs_ndis_init) >= HN_NVS_REQSIZE_MIN); +#define HN_NVS_DATAPATH_SYNTHETIC 0 +#define HN_NVS_DATAPATH_VF 1 + +/* No response */ +struct hn_nvs_datapath { + uint32_t nvs_type; /* HN_NVS_TYPE_SET_DATAPATH */ + uint32_t nvs_active_path;/* HN_NVS_DATAPATH_* */ + uint32_t nvs_rsvd[6]; +} __packed; +CTASSERT(sizeof(struct hn_nvs_datapath) >= HN_NVS_REQSIZE_MIN); + struct hn_nvs_rxbuf_conn { uint32_t nvs_type; /* HN_NVS_TYPE_RXBUF_CONN */ uint32_t nvs_gpadl; /* RXBUF vmbus GPADL */ diff --git a/sys/dev/hyperv/netvsc/if_hnvar.h b/sys/dev/hyperv/netvsc/if_hnvar.h index 7d5d912..9c39830 100644 --- a/sys/dev/hyperv/netvsc/if_hnvar.h +++ b/sys/dev/hyperv/netvsc/if_hnvar.h @@ -59,6 +59,7 @@ struct hn_tx_ring; struct hn_rx_ring { struct ifnet *hn_ifp; + struct ifnet *hn_vf; /* SR-IOV VF */ struct hn_tx_ring *hn_txr; void *hn_pktbuf; int hn_pktbuf_len; @@ -85,6 +86,8 @@ struct hn_rx_ring { void *hn_br; /* TX/RX bufring */ struct hyperv_dma hn_br_dma; + + struct vmbus_channel *hn_chan; } __aligned(CACHE_LINE_SIZE); #define HN_TRUST_HCSUM_IP 0x0001 @@ -233,6 +236,9 @@ struct hn_softc { int hn_rss_ind_size; uint32_t hn_rss_hash; /* NDIS_HASH_ */ struct ndis_rssprm_toeplitz hn_rss; + + eventhandler_tag hn_ifaddr_evthand; + eventhandler_tag hn_ifnet_evthand; }; #define HN_FLAG_RXBUF_CONNECTED 0x0001 @@ -243,6 +249,7 @@ struct hn_softc { #define HN_FLAG_NO_SLEEPING 0x0020 #define HN_FLAG_RXBUF_REF 0x0040 #define HN_FLAG_CHIM_REF 0x0080 +#define HN_FLAG_VF 0x0100 #define HN_FLAG_ERRORS (HN_FLAG_RXBUF_REF | HN_FLAG_CHIM_REF) diff --git a/sys/dev/hyperv/utilities/vmbus_timesync.c b/sys/dev/hyperv/utilities/vmbus_timesync.c index 7610027..66b1e48 100644 --- a/sys/dev/hyperv/utilities/vmbus_timesync.c +++ b/sys/dev/hyperv/utilities/vmbus_timesync.c @@ -52,8 +52,7 @@ __FBSDID("$FreeBSD$"); VMBUS_ICVER_LE(VMBUS_IC_VERSION(4, 0), (sc)->ic_msgver) #define VMBUS_TIMESYNC_DORTT(sc) \ - (VMBUS_TIMESYNC_MSGVER4((sc)) &&\ - (hyperv_features & CPUID_HV_MSR_TIME_REFCNT)) + (VMBUS_TIMESYNC_MSGVER4((sc)) && hyperv_tc64 != NULL) static int vmbus_timesync_probe(device_t); static int vmbus_timesync_attach(device_t); @@ -117,7 +116,7 @@ vmbus_timesync(struct vmbus_ic_softc *sc, uint64_t hvtime, uint64_t sent_tc, uint64_t hv_ns, vm_ns, rtt = 0; if (VMBUS_TIMESYNC_DORTT(sc)) - rtt = rdmsr(MSR_HV_TIME_REF_COUNT) - sent_tc; + rtt = hyperv_tc64() - sent_tc; hv_ns = (hvtime - VMBUS_ICMSG_TS_BASE + rtt) * HYPERV_TIMER_NS_FACTOR; nanotime(&vm_ts); diff --git a/sys/dev/hyperv/vmbus/amd64/hyperv_machdep.c b/sys/dev/hyperv/vmbus/amd64/hyperv_machdep.c index 9caed81..118178f 100644 --- a/sys/dev/hyperv/vmbus/amd64/hyperv_machdep.c +++ b/sys/dev/hyperv/vmbus/amd64/hyperv_machdep.c @@ -118,8 +118,8 @@ hyperv_tsc_mmap(struct cdev *dev __unused, vm_ooffset_t offset, } #define HYPERV_TSC_TIMECOUNT(fence) \ -static u_int \ -hyperv_tsc_timecount_##fence(struct timecounter *tc) \ +static uint64_t \ +hyperv_tc64_tsc_##fence(void) \ { \ struct hyperv_reftsc *tsc_ref = hyperv_ref_tsc.tsc_ref; \ uint32_t seq; \ @@ -150,6 +150,13 @@ hyperv_tsc_timecount_##fence(struct timecounter *tc) \ /* Fallback to the generic timecounter, i.e. rdmsr. */ \ return (rdmsr(MSR_HV_TIME_REF_COUNT)); \ } \ + \ +static u_int \ +hyperv_tsc_timecount_##fence(struct timecounter *tc __unused) \ +{ \ + \ + return (hyperv_tc64_tsc_##fence()); \ +} \ struct __hack HYPERV_TSC_TIMECOUNT(lfence); @@ -158,6 +165,7 @@ HYPERV_TSC_TIMECOUNT(mfence); static void hyperv_tsc_tcinit(void *dummy __unused) { + hyperv_tc64_t tc64 = NULL; uint64_t val, orig; if ((hyperv_features & @@ -170,11 +178,13 @@ hyperv_tsc_tcinit(void *dummy __unused) case CPU_VENDOR_AMD: hyperv_tsc_timecounter.tc_get_timecount = hyperv_tsc_timecount_mfence; + tc64 = hyperv_tc64_tsc_mfence; break; case CPU_VENDOR_INTEL: hyperv_tsc_timecounter.tc_get_timecount = hyperv_tsc_timecount_lfence; + tc64 = hyperv_tc64_tsc_lfence; break; default: @@ -199,6 +209,10 @@ hyperv_tsc_tcinit(void *dummy __unused) /* Register "enlightened" timecounter. */ tc_init(&hyperv_tsc_timecounter); + /* Install 64 bits timecounter method for other modules to use. */ + KASSERT(tc64 != NULL, ("tc64 is not set")); + hyperv_tc64 = tc64; + /* Add device for mmap(2). */ make_dev(&hyperv_tsc_cdevsw, 0, UID_ROOT, GID_WHEEL, 0444, HYPERV_REFTSC_DEVNAME); diff --git a/sys/dev/hyperv/vmbus/hyperv.c b/sys/dev/hyperv/vmbus/hyperv.c index 2df313b..144bff5 100644 --- a/sys/dev/hyperv/vmbus/hyperv.c +++ b/sys/dev/hyperv/vmbus/hyperv.c @@ -77,6 +77,8 @@ u_int hyperv_recommends; static u_int hyperv_pm_features; static u_int hyperv_features3; +hyperv_tc64_t hyperv_tc64; + static struct timecounter hyperv_timecounter = { .tc_get_timecount = hyperv_get_timecount, .tc_poll_pps = NULL, @@ -96,6 +98,13 @@ hyperv_get_timecount(struct timecounter *tc __unused) return rdmsr(MSR_HV_TIME_REF_COUNT); } +static uint64_t +hyperv_tc64_rdmsr(void) +{ + + return (rdmsr(MSR_HV_TIME_REF_COUNT)); +} + uint64_t hypercall_post_message(bus_addr_t msg_paddr) { @@ -232,6 +241,12 @@ hyperv_init(void *dummy __unused) if (hyperv_features & CPUID_HV_MSR_TIME_REFCNT) { /* Register Hyper-V timecounter */ tc_init(&hyperv_timecounter); + + /* + * Install 64 bits timecounter method for other modules + * to use. + */ + hyperv_tc64 = hyperv_tc64_rdmsr; } } SYSINIT(hyperv_initialize, SI_SUB_HYPERVISOR, SI_ORDER_FIRST, hyperv_init, diff --git a/sys/dev/hyperv/vmbus/vmbus_et.c b/sys/dev/hyperv/vmbus/vmbus_et.c index 1e0c746..93f2ffa 100644 --- a/sys/dev/hyperv/vmbus/vmbus_et.c +++ b/sys/dev/hyperv/vmbus/vmbus_et.c @@ -50,13 +50,10 @@ __FBSDID("$FreeBSD$"); MSR_HV_STIMER_CFG_SINT_MASK) /* - * Two additionally required features: + * Additionally required feature: * - SynIC is needed for interrupt generation. - * - Time reference counter is needed to set ABS reference count to - * STIMER0_COUNT. */ -#define CPUID_HV_ET_MASK (CPUID_HV_MSR_TIME_REFCNT | \ - CPUID_HV_MSR_SYNIC | \ +#define CPUID_HV_ET_MASK (CPUID_HV_MSR_SYNIC | \ CPUID_HV_MSR_SYNTIMER) static void vmbus_et_identify(driver_t *, device_t); @@ -104,7 +101,7 @@ vmbus_et_start(struct eventtimer *et __unused, sbintime_t first, { uint64_t current; - current = rdmsr(MSR_HV_TIME_REF_COUNT); + current = hyperv_tc64(); current += hyperv_sbintime2count(first); wrmsr(MSR_HV_STIMER0_COUNT, current); @@ -133,7 +130,8 @@ vmbus_et_identify(driver_t *driver, device_t parent) { if (device_get_unit(parent) != 0 || device_find_child(parent, VMBUS_ET_NAME, -1) != NULL || - (hyperv_features & CPUID_HV_ET_MASK) != CPUID_HV_ET_MASK) + (hyperv_features & CPUID_HV_ET_MASK) != CPUID_HV_ET_MASK || + hyperv_tc64 == NULL) return; device_add_child(parent, VMBUS_ET_NAME, -1); @@ -189,9 +187,8 @@ vmbus_et_attach(device_t dev) vmbus_et.et_start = vmbus_et_start; /* - * Delay a bit to make sure that MSR_HV_TIME_REF_COUNT will - * not return 0, since writing 0 to STIMER0_COUNT will disable - * STIMER0. + * Delay a bit to make sure that hyperv_tc64 will not return 0, + * since writing 0 to STIMER0_COUNT will disable STIMER0. */ DELAY(100); smp_rendezvous(NULL, vmbus_et_config, NULL, NULL); diff --git a/sys/dev/isp/isp.c b/sys/dev/isp/isp.c index 9d38f60..c77bda5 100644 --- a/sys/dev/isp/isp.c +++ b/sys/dev/isp/isp.c @@ -4451,11 +4451,7 @@ isp_start(XS_T *xs) if (XS_TAG_P(xs)) { ttype = XS_TAG_TYPE(xs); } else { - if (XS_CDBP(xs)[0] == 0x3) { - ttype = REQFLAG_HTAG; - } else { - ttype = REQFLAG_STAG; - } + ttype = REQFLAG_STAG; } if (ttype == REQFLAG_OTAG) { ttype = FCP_CMND_TASK_ATTR_ORDERED; @@ -4479,14 +4475,7 @@ isp_start(XS_T *xs) if (XS_TAG_P(xs)) { ((ispreqt2_t *)reqp)->req_flags = XS_TAG_TYPE(xs); } else { - /* - * If we don't know what tag to use, use HEAD OF QUEUE - * for Request Sense or Simple. - */ - if (XS_CDBP(xs)[0] == 0x3) /* REQUEST SENSE */ - ((ispreqt2_t *)reqp)->req_flags = REQFLAG_HTAG; - else - ((ispreqt2_t *)reqp)->req_flags = REQFLAG_STAG; + ((ispreqt2_t *)reqp)->req_flags = REQFLAG_STAG; } } else { sdparam *sdp = SDPARAM(isp, XS_CHANNEL(xs)); diff --git a/sys/dev/nand/nand_geom.c b/sys/dev/nand/nand_geom.c index 98373aa..913958a 100644 --- a/sys/dev/nand/nand_geom.c +++ b/sys/dev/nand/nand_geom.c @@ -416,7 +416,7 @@ create_geom_disk(struct nand_chip *chip) snprintf(rdisk->d_ident, sizeof(rdisk->d_ident), "nand_raw: Man:0x%02x Dev:0x%02x", chip->id.man_id, chip->id.dev_id); - disk->d_rotation_rate = DISK_RR_NON_ROTATING; + rdisk->d_rotation_rate = DISK_RR_NON_ROTATING; disk_create(rdisk, DISK_VERSION); diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c index 26cf526..d36f4cc 100644 --- a/sys/dev/pci/pci.c +++ b/sys/dev/pci/pci.c @@ -269,13 +269,14 @@ static const struct pci_quirk pci_quirks[] = { { 0x43851002, PCI_QUIRK_UNMAP_REG, 0x14, 0 }, /* - * Atheros AR8161/AR8162/E2200/E2400 Ethernet controllers have a - * bug that MSI interrupt does not assert if PCIM_CMD_INTxDIS bit + * Atheros AR8161/AR8162/E2200/E2400/E2500 Ethernet controllers have + * a bug that MSI interrupt does not assert if PCIM_CMD_INTxDIS bit * of the command register is set. */ { 0x10911969, PCI_QUIRK_MSI_INTX_BUG, 0, 0 }, { 0xE0911969, PCI_QUIRK_MSI_INTX_BUG, 0, 0 }, { 0xE0A11969, PCI_QUIRK_MSI_INTX_BUG, 0, 0 }, + { 0xE0B11969, PCI_QUIRK_MSI_INTX_BUG, 0, 0 }, { 0x10901969, PCI_QUIRK_MSI_INTX_BUG, 0, 0 }, /* diff --git a/sys/dev/ppbus/vpo.c b/sys/dev/ppbus/vpo.c index a4f5226..f508275 100644 --- a/sys/dev/ppbus/vpo.c +++ b/sys/dev/ppbus/vpo.c @@ -316,7 +316,7 @@ vpo_action(struct cam_sim *sim, union ccb *ccb) } #ifdef VP0_DEBUG device_printf(vpo->vpo_dev, "XPT_SCSI_IO (0x%x) request\n", - scsiio_cdb_ptr(csio)); + *scsiio_cdb_ptr(csio)); #endif vpo_intr(vpo, csio); |