diff options
Diffstat (limited to 'freebsd/sys/dev')
42 files changed, 916 insertions, 318 deletions
diff --git a/freebsd/sys/dev/bfe/if_bfe.c b/freebsd/sys/dev/bfe/if_bfe.c index c07d87fb..f1586d59 100644 --- a/freebsd/sys/dev/bfe/if_bfe.c +++ b/freebsd/sys/dev/bfe/if_bfe.c @@ -159,6 +159,8 @@ static driver_t bfe_driver = { static devclass_t bfe_devclass; DRIVER_MODULE(bfe, pci, bfe_driver, bfe_devclass, 0, 0); +MODULE_PNP_INFO("U16:vendor;U16:device;D:#", pci, bfe, bfe_devs, + sizeof(bfe_devs[0]), nitems(bfe_devs) - 1); DRIVER_MODULE(miibus, bfe, miibus_driver, miibus_devclass, 0, 0); /* diff --git a/freebsd/sys/dev/bge/if_bge.c b/freebsd/sys/dev/bge/if_bge.c index aba0b05d..260c6c23 100644 --- a/freebsd/sys/dev/bge/if_bge.c +++ b/freebsd/sys/dev/bge/if_bge.c @@ -549,6 +549,8 @@ static driver_t bge_driver = { static devclass_t bge_devclass; DRIVER_MODULE(bge, pci, bge_driver, bge_devclass, 0, 0); +MODULE_PNP_INFO("U16:vendor;U16:device", pci, bge, bge_devs, + sizeof(bge_devs[0]), nitems(bge_devs) - 1); DRIVER_MODULE(miibus, bge, miibus_driver, miibus_devclass, 0, 0); static int bge_allow_asf = 1; @@ -3212,6 +3214,14 @@ bge_can_use_msi(struct bge_softc *sc) sc->bge_chiprev != BGE_CHIPREV_5750_BX) can_use_msi = 1; break; + case BGE_ASICREV_BCM5784: + /* + * Prevent infinite "watchdog timeout" errors + * in some MacBook Pro and make it work out-of-the-box. + */ + if (sc->bge_chiprev == BGE_CHIPREV_5784_AX) + break; + /* FALLTHROUGH */ default: if (BGE_IS_575X_PLUS(sc)) can_use_msi = 1; @@ -6716,15 +6726,15 @@ bge_sysctl_mem_read(SYSCTL_HANDLER_ARGS) static int bge_get_eaddr_fw(struct bge_softc *sc, uint8_t ether_addr[]) { - +#ifdef __sparc64__ if (sc->bge_flags & BGE_FLAG_EADDR) return (1); -#ifdef __sparc64__ OF_getetheraddr(sc->bge_dev, ether_addr); return (0); -#endif +#else return (1); +#endif } static int diff --git a/freebsd/sys/dev/dc/if_dc.c b/freebsd/sys/dev/dc/if_dc.c index ac34a20a..14023e54 100644 --- a/freebsd/sys/dev/dc/if_dc.c +++ b/freebsd/sys/dev/dc/if_dc.c @@ -361,6 +361,8 @@ static devclass_t dc_devclass; DRIVER_MODULE_ORDERED(dc, pci, dc_driver, dc_devclass, NULL, NULL, SI_ORDER_ANY); +MODULE_PNP_INFO("W32:vendor/device;U8:revision;D:#", pci, dc, dc_devs, + sizeof(dc_devs[0]), nitems(dc_devs) - 1); DRIVER_MODULE(miibus, dc, miibus_driver, miibus_devclass, NULL, NULL); #define DC_SETBIT(sc, reg, x) \ diff --git a/freebsd/sys/dev/e1000/if_em.c b/freebsd/sys/dev/e1000/if_em.c index 72711a6e..4fe66dfc 100644 --- a/freebsd/sys/dev/e1000/if_em.c +++ b/freebsd/sys/dev/e1000/if_em.c @@ -412,7 +412,6 @@ static driver_t em_if_driver = { #define EM_TICKS_TO_USECS(ticks) ((1024 * (ticks) + 500) / 1000) #define EM_USECS_TO_TICKS(usecs) ((1000 * (usecs) + 512) / 1024) -#define M_TSO_LEN 66 #define MAX_INTS_PER_SEC 8000 #define DEFAULT_ITR (1000000000/(MAX_INTS_PER_SEC * 256)) @@ -422,8 +421,6 @@ static driver_t em_if_driver = { #define CSUM_TSO 0 #endif -#define TSO_WORKAROUND 4 - static SYSCTL_NODE(_hw, OID_AUTO, em, CTLFLAG_RD, 0, "EM driver parameters"); static int em_disable_crc_stripping = 0; @@ -486,8 +483,10 @@ extern struct if_txrx lem_txrx; static struct if_shared_ctx em_sctx_init = { .isc_magic = IFLIB_MAGIC, .isc_q_align = PAGE_SIZE, - .isc_tx_maxsize = EM_TSO_SIZE, + .isc_tx_maxsize = EM_TSO_SIZE + sizeof(struct ether_vlan_header), .isc_tx_maxsegsize = PAGE_SIZE, + .isc_tso_maxsize = EM_TSO_SIZE + sizeof(struct ether_vlan_header), + .isc_tso_maxsegsize = EM_TSO_SEG_SIZE, .isc_rx_maxsize = MJUM9BYTES, .isc_rx_nsegments = 1, .isc_rx_maxsegsize = MJUM9BYTES, @@ -510,12 +509,13 @@ static struct if_shared_ctx em_sctx_init = { if_shared_ctx_t em_sctx = &em_sctx_init; - static struct if_shared_ctx igb_sctx_init = { .isc_magic = IFLIB_MAGIC, .isc_q_align = PAGE_SIZE, - .isc_tx_maxsize = EM_TSO_SIZE, + .isc_tx_maxsize = EM_TSO_SIZE + sizeof(struct ether_vlan_header), .isc_tx_maxsegsize = PAGE_SIZE, + .isc_tso_maxsize = EM_TSO_SIZE + sizeof(struct ether_vlan_header), + .isc_tso_maxsegsize = EM_TSO_SEG_SIZE, .isc_rx_maxsize = MJUM9BYTES, .isc_rx_nsegments = 1, .isc_rx_maxsegsize = MJUM9BYTES, @@ -699,16 +699,19 @@ em_set_num_queues(if_ctx_t ctx) return (maxqueues); } +#define LEM_CAPS \ + IFCAP_HWCSUM | IFCAP_VLAN_MTU | IFCAP_VLAN_HWTAGGING | \ + IFCAP_VLAN_HWCSUM | IFCAP_WOL | IFCAP_VLAN_HWFILTER -#define EM_CAPS \ - IFCAP_TSO4 | IFCAP_TXCSUM | IFCAP_LRO | IFCAP_RXCSUM | IFCAP_VLAN_HWFILTER | IFCAP_WOL_MAGIC | \ - IFCAP_WOL_MCAST | IFCAP_WOL | IFCAP_VLAN_HWTSO | IFCAP_HWCSUM | IFCAP_VLAN_HWTAGGING | \ - IFCAP_VLAN_HWCSUM | IFCAP_VLAN_HWTSO | IFCAP_VLAN_MTU; +#define EM_CAPS \ + IFCAP_HWCSUM | IFCAP_VLAN_MTU | IFCAP_VLAN_HWTAGGING | \ + IFCAP_VLAN_HWCSUM | IFCAP_WOL | IFCAP_VLAN_HWFILTER | IFCAP_TSO4 | \ + IFCAP_LRO | IFCAP_VLAN_HWTSO -#define IGB_CAPS \ - IFCAP_TSO4 | IFCAP_TXCSUM | IFCAP_LRO | IFCAP_RXCSUM | IFCAP_VLAN_HWFILTER | IFCAP_WOL_MAGIC | \ - IFCAP_WOL_MCAST | IFCAP_WOL | IFCAP_VLAN_HWTSO | IFCAP_HWCSUM | IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_HWCSUM | \ - IFCAP_VLAN_HWTSO | IFCAP_VLAN_MTU | IFCAP_TXCSUM_IPV6 | IFCAP_HWCSUM_IPV6 | IFCAP_JUMBO_MTU; +#define IGB_CAPS \ + IFCAP_HWCSUM | IFCAP_VLAN_MTU | IFCAP_VLAN_HWTAGGING | \ + IFCAP_VLAN_HWCSUM | IFCAP_WOL | IFCAP_VLAN_HWFILTER | IFCAP_TSO4 | \ + IFCAP_LRO | IFCAP_VLAN_HWTSO | IFCAP_JUMBO_MTU | IFCAP_HWCSUM_IPV6; /********************************************************************* * Device initialization routine @@ -775,18 +778,11 @@ em_if_attach_pre(if_ctx_t ctx) /* Determine hardware and mac info */ em_identify_hardware(ctx); - /* Set isc_msix_bar */ scctx->isc_msix_bar = PCIR_BAR(EM_MSIX_BAR); scctx->isc_tx_nsegments = EM_MAX_SCATTER; - scctx->isc_tx_tso_segments_max = scctx->isc_tx_nsegments; - scctx->isc_tx_tso_size_max = EM_TSO_SIZE; - scctx->isc_tx_tso_segsize_max = EM_TSO_SEG_SIZE; scctx->isc_nrxqsets_max = scctx->isc_ntxqsets_max = em_set_num_queues(ctx); device_printf(dev, "attach_pre capping queues at %d\n", scctx->isc_ntxqsets_max); - scctx->isc_tx_csum_flags = CSUM_TCP | CSUM_UDP | CSUM_IP_TSO; - - if (adapter->hw.mac.type >= igb_mac_min) { int try_second_bar; @@ -795,9 +791,12 @@ em_if_attach_pre(if_ctx_t ctx) scctx->isc_txd_size[0] = sizeof(union e1000_adv_tx_desc); scctx->isc_rxd_size[0] = sizeof(union e1000_adv_rx_desc); scctx->isc_txrx = &igb_txrx; - scctx->isc_capenable = IGB_CAPS; - scctx->isc_tx_csum_flags = CSUM_TCP | CSUM_UDP | CSUM_TSO | CSUM_IP6_TCP \ - | CSUM_IP6_UDP | CSUM_IP6_TCP; + scctx->isc_tx_tso_segments_max = EM_MAX_SCATTER; + scctx->isc_tx_tso_size_max = EM_TSO_SIZE; + scctx->isc_tx_tso_segsize_max = EM_TSO_SEG_SIZE; + scctx->isc_capabilities = scctx->isc_capenable = IGB_CAPS; + scctx->isc_tx_csum_flags = CSUM_TCP | CSUM_UDP | CSUM_TSO | + CSUM_IP6_TCP | CSUM_IP6_UDP; if (adapter->hw.mac.type != e1000_82575) scctx->isc_tx_csum_flags |= CSUM_SCTP | CSUM_IP6_SCTP; @@ -809,26 +808,44 @@ em_if_attach_pre(if_ctx_t ctx) try_second_bar = pci_read_config(dev, scctx->isc_msix_bar, 4); if (try_second_bar == 0) scctx->isc_msix_bar += 4; - } else if (adapter->hw.mac.type >= em_mac_min) { scctx->isc_txqsizes[0] = roundup2(scctx->isc_ntxd[0]* sizeof(struct e1000_tx_desc), EM_DBA_ALIGN); scctx->isc_rxqsizes[0] = roundup2(scctx->isc_nrxd[0] * sizeof(union e1000_rx_desc_extended), EM_DBA_ALIGN); scctx->isc_txd_size[0] = sizeof(struct e1000_tx_desc); scctx->isc_rxd_size[0] = sizeof(union e1000_rx_desc_extended); scctx->isc_txrx = &em_txrx; - scctx->isc_capenable = EM_CAPS; + scctx->isc_tx_tso_segments_max = EM_MAX_SCATTER; + scctx->isc_tx_tso_size_max = EM_TSO_SIZE; + scctx->isc_tx_tso_segsize_max = EM_TSO_SEG_SIZE; + scctx->isc_capabilities = scctx->isc_capenable = EM_CAPS; + /* + * For EM-class devices, don't enable IFCAP_{TSO4,VLAN_HWTSO} + * by default as we don't have workarounds for all associated + * silicon errata. E. g., with several MACs such as 82573E, + * TSO only works at Gigabit speed and otherwise can cause the + * hardware to hang (which also would be next to impossible to + * work around given that already queued TSO-using descriptors + * would need to be flushed and vlan(4) reconfigured at runtime + * in case of a link speed change). Moreover, MACs like 82579 + * still can hang at Gigabit even with all publicly documented + * TSO workarounds implemented. Generally, the penality of + * these workarounds is rather high and may involve copying + * mbuf data around so advantages of TSO lapse. Still, TSO may + * work for a few MACs of this class - at least when sticking + * with Gigabit - in which case users may enable TSO manually. + */ + scctx->isc_capenable &= ~(IFCAP_TSO4 | IFCAP_VLAN_HWTSO); scctx->isc_tx_csum_flags = CSUM_TCP | CSUM_UDP | CSUM_IP_TSO; } else { scctx->isc_txqsizes[0] = roundup2((scctx->isc_ntxd[0] + 1) * sizeof(struct e1000_tx_desc), EM_DBA_ALIGN); scctx->isc_rxqsizes[0] = roundup2((scctx->isc_nrxd[0] + 1) * sizeof(struct e1000_rx_desc), EM_DBA_ALIGN); scctx->isc_txd_size[0] = sizeof(struct e1000_tx_desc); scctx->isc_rxd_size[0] = sizeof(struct e1000_rx_desc); - scctx->isc_tx_csum_flags = CSUM_TCP | CSUM_UDP | CSUM_IP_TSO; + scctx->isc_tx_csum_flags = CSUM_TCP | CSUM_UDP; scctx->isc_txrx = &lem_txrx; - scctx->isc_capenable = EM_CAPS; + scctx->isc_capabilities = scctx->isc_capenable = LEM_CAPS; if (adapter->hw.mac.type < e1000_82543) scctx->isc_capenable &= ~(IFCAP_HWCSUM|IFCAP_VLAN_HWCSUM); - scctx->isc_tx_csum_flags = CSUM_TCP | CSUM_UDP | CSUM_IP_TSO; scctx->isc_msix_bar = 0; } @@ -1009,6 +1026,11 @@ em_if_attach_pre(if_ctx_t ctx) */ em_get_wakeup(ctx); + /* Enable only WOL MAGIC by default */ + scctx->isc_capenable &= ~IFCAP_WOL; + if (adapter->wol != 0) + scctx->isc_capenable |= IFCAP_WOL_MAGIC; + iflib_set_mac(ctx, hw->mac.addr); return (0); @@ -1702,7 +1724,6 @@ em_if_update_admin_status(if_ctx_t ctx) { struct adapter *adapter = iflib_get_softc(ctx); struct e1000_hw *hw = &adapter->hw; - struct ifnet *ifp = iflib_get_ifp(ctx); device_t dev = iflib_get_dev(ctx); u32 link_check, thstat, ctrl; @@ -1766,8 +1787,8 @@ em_if_update_admin_status(if_ctx_t ctx) "Full Duplex" : "Half Duplex")); adapter->link_active = 1; adapter->smartspeed = 0; - if_setbaudrate(ifp, adapter->link_speed * 1000000); - if ((ctrl & E1000_CTRL_EXT_LINK_MODE_GMII) && + if ((ctrl & E1000_CTRL_EXT_LINK_MODE_MASK) == + E1000_CTRL_EXT_LINK_MODE_GMII && (thstat & E1000_THSTAT_LINK_THROTTLE)) device_printf(dev, "Link: thermal downshift\n"); /* Delay Link Up for Phy update */ @@ -1782,17 +1803,15 @@ em_if_update_admin_status(if_ctx_t ctx) adapter->flags |= IGB_MEDIA_RESET; em_reset(ctx); } - iflib_link_state_change(ctx, LINK_STATE_UP, ifp->if_baudrate); + iflib_link_state_change(ctx, LINK_STATE_UP, + IF_Mbps(adapter->link_speed)); printf("Link state changed to up\n"); } else if (!link_check && (adapter->link_active == 1)) { - if_setbaudrate(ifp, 0); adapter->link_speed = 0; adapter->link_duplex = 0; - if (bootverbose) - device_printf(dev, "Link is Down\n"); adapter->link_active = 0; - iflib_link_state_change(ctx, LINK_STATE_DOWN, ifp->if_baudrate); - printf("link state changed to down\n"); + iflib_link_state_change(ctx, LINK_STATE_DOWN, 0); + printf("Link state changed to down\n"); } em_update_stats_counters(adapter); @@ -1965,7 +1984,6 @@ em_if_msix_intr_assign(if_ctx_t ctx, int msix) vector = 0; for (i = 0; i < adapter->tx_num_queues; i++, tx_que++, vector++) { - rid = vector + 1; snprintf(buf, sizeof(buf), "txq%d", i); tx_que = &adapter->tx_queues[i]; iflib_softirq_alloc_generic(ctx, @@ -2304,7 +2322,7 @@ igb_init_dmac(struct adapter *adapter, u32 pba) dmac = pba - 10; reg = E1000_READ_REG(hw, E1000_DMACR); reg &= ~E1000_DMACR_DMACTHR_MASK; - reg = ((dmac << E1000_DMACR_DMACTHR_SHIFT) + reg |= ((dmac << E1000_DMACR_DMACTHR_SHIFT) & E1000_DMACR_DMACTHR_MASK); /* transition to L0x or L1 if available..*/ @@ -2752,51 +2770,15 @@ em_setup_interface(if_ctx_t ctx) struct ifnet *ifp = iflib_get_ifp(ctx); struct adapter *adapter = iflib_get_softc(ctx); if_softc_ctx_t scctx = adapter->shared; - uint64_t cap = 0; INIT_DEBUGOUT("em_setup_interface: begin"); - /* TSO parameters */ - if_sethwtsomax(ifp, IP_MAXPACKET); - /* Take m_pullup(9)'s in em_xmit() w/ TSO into acount. */ - if_sethwtsomaxsegcount(ifp, EM_MAX_SCATTER - 5); - if_sethwtsomaxsegsize(ifp, EM_TSO_SEG_SIZE); - /* Single Queue */ if (adapter->tx_num_queues == 1) { if_setsendqlen(ifp, scctx->isc_ntxd[0] - 1); if_setsendqready(ifp); } - cap = IFCAP_HWCSUM | IFCAP_VLAN_HWCSUM | IFCAP_TSO4; - cap |= IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_HWTSO | IFCAP_VLAN_MTU; - - /* - * Tell the upper layer(s) we - * support full VLAN capability - */ - if_setifheaderlen(ifp, sizeof(struct ether_vlan_header)); - if_setcapabilitiesbit(ifp, cap, 0); - - /* - * Don't turn this on by default, if vlans are - * created on another pseudo device (eg. lagg) - * then vlan events are not passed thru, breaking - * operation, but with HW FILTER off it works. If - * using vlans directly on the em driver you can - * enable this and get full hardware tag filtering. - */ - if_setcapabilitiesbit(ifp, IFCAP_VLAN_HWFILTER,0); - - /* Enable only WOL MAGIC by default */ - if (adapter->wol) { - if_setcapenablebit(ifp, IFCAP_WOL_MAGIC, - IFCAP_WOL_MCAST| IFCAP_WOL_UCAST); - } else { - if_setcapenablebit(ifp, 0, IFCAP_WOL_MAGIC | - IFCAP_WOL_MCAST| IFCAP_WOL_UCAST); - } - /* * Specify the media types supported by this adapter and register * callbacks to update media and link information diff --git a/freebsd/sys/dev/e1000/if_em.h b/freebsd/sys/dev/e1000/if_em.h index 0c892947..26bdcb2e 100644 --- a/freebsd/sys/dev/e1000/if_em.h +++ b/freebsd/sys/dev/e1000/if_em.h @@ -250,11 +250,6 @@ #define IGB_LINK_ITR 2000 #define I210_LINK_DELAY 1000 -#define IGB_MAX_SCATTER 40 -#define IGB_VFTA_SIZE 128 -#define IGB_BR_SIZE 4096 /* ring buf size */ -#define IGB_TSO_SIZE (65535 + sizeof(struct ether_vlan_header)) -#define IGB_TSO_SEG_SIZE 4096 /* Max dma segment size */ #define IGB_TXPBSIZE 20408 #define IGB_HDR_BUF 128 #define IGB_PKTTYPE_MASK 0x0000FFF0 @@ -340,7 +335,7 @@ #define EM_MAX_SCATTER 40 #define EM_VFTA_SIZE 128 -#define EM_TSO_SIZE (65535 + sizeof(struct ether_vlan_header)) +#define EM_TSO_SIZE 65535 #define EM_TSO_SEG_SIZE 4096 /* Max dma segment size */ #define EM_MSIX_MASK 0x01F00000 /* For 82574 use */ #define EM_MSIX_LINK 0x01000000 /* For 82574 use */ diff --git a/freebsd/sys/dev/evdev/cdev.c b/freebsd/sys/dev/evdev/cdev.c index 10f4e77e..5ae14fed 100644 --- a/freebsd/sys/dev/evdev/cdev.c +++ b/freebsd/sys/dev/evdev/cdev.c @@ -421,7 +421,7 @@ evdev_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, return (ENOTSUP); ke = (struct input_keymap_entry *)data; - evdev->ev_methods->ev_get_keycode(evdev, evdev->ev_softc, ke); + evdev->ev_methods->ev_get_keycode(evdev, ke); return (0); case EVIOCSKEYCODE: @@ -434,7 +434,7 @@ evdev_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, return (ENOTSUP); ke = (struct input_keymap_entry *)data; - evdev->ev_methods->ev_set_keycode(evdev, evdev->ev_softc, ke); + evdev->ev_methods->ev_set_keycode(evdev, ke); return (0); case EVIOCGABS(0) ... EVIOCGABS(ABS_MAX): diff --git a/freebsd/sys/dev/evdev/evdev.c b/freebsd/sys/dev/evdev/evdev.c index 6c2976d7..a355ec50 100644 --- a/freebsd/sys/dev/evdev/evdev.c +++ b/freebsd/sys/dev/evdev/evdev.c @@ -343,6 +343,13 @@ evdev_set_methods(struct evdev_dev *evdev, void *softc, evdev->ev_softc = softc; } +inline void * +evdev_get_softc(struct evdev_dev *evdev) +{ + + return (evdev->ev_softc); +} + inline void evdev_support_prop(struct evdev_dev *evdev, uint16_t prop) { @@ -804,8 +811,7 @@ evdev_inject_event(struct evdev_dev *evdev, uint16_t type, uint16_t code, case EV_FF: if (evdev->ev_methods != NULL && evdev->ev_methods->ev_event != NULL) - evdev->ev_methods->ev_event(evdev, evdev->ev_softc, - type, code, value); + evdev->ev_methods->ev_event(evdev, type, code, value); /* * Leds and driver repeats should be reported in ev_event * method body to interoperate with kbdmux states and rates @@ -848,7 +854,7 @@ evdev_register_client(struct evdev_dev *evdev, struct evdev_client *client) evdev->ev_methods->ev_open != NULL) { debugf(evdev, "calling ev_open() on device %s", evdev->ev_shortname); - ret = evdev->ev_methods->ev_open(evdev, evdev->ev_softc); + ret = evdev->ev_methods->ev_open(evdev); } if (ret == 0) LIST_INSERT_HEAD(&evdev->ev_clients, client, ec_link); @@ -866,7 +872,7 @@ evdev_dispose_client(struct evdev_dev *evdev, struct evdev_client *client) if (LIST_EMPTY(&evdev->ev_clients)) { if (evdev->ev_methods != NULL && evdev->ev_methods->ev_close != NULL) - evdev->ev_methods->ev_close(evdev, evdev->ev_softc); + (void)evdev->ev_methods->ev_close(evdev); if (evdev_event_supported(evdev, EV_REP) && bit_test(evdev->ev_flags, EVDEV_FLAG_SOFTREPEAT)) evdev_stop_repeat(evdev); diff --git a/freebsd/sys/dev/evdev/evdev.h b/freebsd/sys/dev/evdev/evdev.h index 31f0c2c3..b897a465 100644 --- a/freebsd/sys/dev/evdev/evdev.h +++ b/freebsd/sys/dev/evdev/evdev.h @@ -38,11 +38,10 @@ struct evdev_dev; -typedef int (evdev_open_t)(struct evdev_dev *, void *); -typedef void (evdev_close_t)(struct evdev_dev *, void *); -typedef void (evdev_event_t)(struct evdev_dev *, void *, uint16_t, - uint16_t, int32_t); -typedef void (evdev_keycode_t)(struct evdev_dev *, void *, +typedef int (evdev_open_t)(struct evdev_dev *); +typedef int (evdev_close_t)(struct evdev_dev *); +typedef void (evdev_event_t)(struct evdev_dev *, uint16_t, uint16_t, int32_t); +typedef void (evdev_keycode_t)(struct evdev_dev *, struct input_keymap_entry *); /* @@ -126,6 +125,7 @@ void evdev_support_sw(struct evdev_dev *, uint16_t); void evdev_set_repeat_params(struct evdev_dev *, uint16_t, int); int evdev_set_report_size(struct evdev_dev *, size_t); void evdev_set_flag(struct evdev_dev *, uint16_t); +void *evdev_get_softc(struct evdev_dev *); /* Multitouch related functions: */ int32_t evdev_get_mt_slot_by_tracking_id(struct evdev_dev *, int32_t); @@ -141,7 +141,6 @@ uint16_t evdev_scancode2key(int *, int); void evdev_push_mouse_btn(struct evdev_dev *, int); void evdev_push_leds(struct evdev_dev *, int); void evdev_push_repeats(struct evdev_dev *, keyboard_t *); -evdev_event_t evdev_ev_kbd_event; /* Event reporting shortcuts: */ static __inline int diff --git a/freebsd/sys/dev/evdev/evdev_utils.c b/freebsd/sys/dev/evdev/evdev_utils.c index 9814ffeb..17a815fb 100644 --- a/freebsd/sys/dev/evdev/evdev_utils.c +++ b/freebsd/sys/dev/evdev/evdev_utils.c @@ -42,8 +42,6 @@ #include <dev/evdev/evdev.h> #include <dev/evdev/input.h> -#include <dev/kbd/kbdreg.h> - #define NONE KEY_RESERVED static uint16_t evdev_usb_scancodes[256] = { @@ -301,43 +299,3 @@ evdev_push_repeats(struct evdev_dev *evdev, keyboard_t *kbd) evdev_push_event(evdev, EV_REP, REP_DELAY, kbd->kb_delay1); evdev_push_event(evdev, EV_REP, REP_PERIOD, kbd->kb_delay2); } - -void -evdev_ev_kbd_event(struct evdev_dev *evdev, void *softc, uint16_t type, - uint16_t code, int32_t value) -{ - keyboard_t *kbd = (keyboard_t *)softc; - int delay[2], leds, oleds; - size_t i; - - if (type == EV_LED) { - leds = oleds = KBD_LED_VAL(kbd); - for (i = 0; i < nitems(evdev_led_codes); i++) { - if (evdev_led_codes[i] == code) { - if (value) - leds |= 1 << i; - else - leds &= ~(1 << i); - if (leds != oleds) { - mtx_lock(&Giant); - kbdd_ioctl(kbd, KDSETLED, - (caddr_t)&leds); - mtx_unlock(&Giant); - } - break; - } - } - } else if (type == EV_REP && code == REP_DELAY) { - delay[0] = value; - delay[1] = kbd->kb_delay2; - mtx_lock(&Giant); - kbdd_ioctl(kbd, KDSETREPEAT, (caddr_t)delay); - mtx_unlock(&Giant); - } else if (type == EV_REP && code == REP_PERIOD) { - delay[0] = kbd->kb_delay1; - delay[1] = value; - mtx_lock(&Giant); - kbdd_ioctl(kbd, KDSETREPEAT, (caddr_t)delay); - mtx_unlock(&Giant); - } -} diff --git a/freebsd/sys/dev/evdev/input-event-codes.h b/freebsd/sys/dev/evdev/input-event-codes.h index cc1528f6..61c9000b 100644 --- a/freebsd/sys/dev/evdev/input-event-codes.h +++ b/freebsd/sys/dev/evdev/input-event-codes.h @@ -421,6 +421,7 @@ #define BTN_TOOL_MOUSE 0x146 #define BTN_TOOL_LENS 0x147 #define BTN_TOOL_QUINTTAP 0x148 /* Five fingers on trackpad */ +#define BTN_STYLUS3 0x149 #define BTN_TOUCH 0x14a #define BTN_STYLUS 0x14b #define BTN_STYLUS2 0x14c @@ -607,6 +608,7 @@ #define BTN_DPAD_RIGHT 0x223 #define KEY_ALS_TOGGLE 0x230 /* Ambient light sensor */ +#define KEY_ROTATE_LOCK_TOGGLE 0x231 /* Display rotation lock */ #define KEY_BUTTONCONFIG 0x240 /* AL Button Configuration */ #define KEY_TASKMANAGER 0x241 /* AL Task/Project Manager */ @@ -615,6 +617,7 @@ #define KEY_APPSELECT 0x244 /* AL Select Task/Application */ #define KEY_SCREENSAVER 0x245 /* AL Screen Saver */ #define KEY_VOICECOMMAND 0x246 /* Listening Voice Command */ +#define KEY_ASSISTANT 0x247 /* AL Context-aware desktop assistant */ #define KEY_BRIGHTNESS_MIN 0x250 /* Set Brightness to Minimum */ #define KEY_BRIGHTNESS_MAX 0x251 /* Set Brightness to Maximum */ @@ -626,6 +629,38 @@ #define KEY_KBDINPUTASSIST_ACCEPT 0x264 #define KEY_KBDINPUTASSIST_CANCEL 0x265 +/* Diagonal movement keys */ +#define KEY_RIGHT_UP 0x266 +#define KEY_RIGHT_DOWN 0x267 +#define KEY_LEFT_UP 0x268 +#define KEY_LEFT_DOWN 0x269 + +#define KEY_ROOT_MENU 0x26a /* Show Device's Root Menu */ +/* Show Top Menu of the Media (e.g. DVD) */ +#define KEY_MEDIA_TOP_MENU 0x26b +#define KEY_NUMERIC_11 0x26c +#define KEY_NUMERIC_12 0x26d +/* + * Toggle Audio Description: refers to an audio service that helps blind and + * visually impaired consumers understand the action in a program. Note: in + * some countries this is referred to as "Video Description". + */ +#define KEY_AUDIO_DESC 0x26e +#define KEY_3D_MODE 0x26f +#define KEY_NEXT_FAVORITE 0x270 +#define KEY_STOP_RECORD 0x271 +#define KEY_PAUSE_RECORD 0x272 +#define KEY_VOD 0x273 /* Video on Demand */ +#define KEY_UNMUTE 0x274 +#define KEY_FASTREVERSE 0x275 +#define KEY_SLOWREVERSE 0x276 +/* + * Control a data application associated with the currently viewed channel, + * e.g. teletext or data broadcast application (MHEG, MHP, HbbTV, etc.) + */ +#define KEY_DATA 0x277 +#define KEY_ONSCREEN_KEYBOARD 0x278 + #define BTN_TRIGGER_HAPPY 0x2c0 #define BTN_TRIGGER_HAPPY1 0x2c0 #define BTN_TRIGGER_HAPPY2 0x2c1 @@ -763,6 +798,7 @@ #define SW_ROTATE_LOCK 0x0c /* set = rotate locked/disabled */ #define SW_LINEIN_INSERT 0x0d /* set = inserted */ #define SW_MUTE_DEVICE 0x0e /* set = device disabled */ +#define SW_PEN_INSERTED 0x0f /* set = pen inserted */ #define SW_MAX 0x0f #define SW_CNT (SW_MAX+1) diff --git a/freebsd/sys/dev/evdev/input.h b/freebsd/sys/dev/evdev/input.h index 7639e0d6..947f4643 100644 --- a/freebsd/sys/dev/evdev/input.h +++ b/freebsd/sys/dev/evdev/input.h @@ -38,6 +38,9 @@ #include "input-event-codes.h" +#define input_event_sec time.tv_sec +#define input_event_usec time.tv_usec + struct input_event { struct timeval time; uint16_t type; @@ -138,6 +141,9 @@ struct input_keymap_entry { #define BUS_GSC 0x1A #define BUS_ATARI 0x1B #define BUS_SPI 0x1C +#define BUS_RMI 0x1D +#define BUS_CEC 0x1E +#define BUS_INTEL_ISHTP 0x1F /* * MT_TOOL types diff --git a/freebsd/sys/dev/evdev/uinput.c b/freebsd/sys/dev/evdev/uinput.c index 3b332d1f..28d740cc 100644 --- a/freebsd/sys/dev/evdev/uinput.c +++ b/freebsd/sys/dev/evdev/uinput.c @@ -161,10 +161,10 @@ uinput_knl_assert_unlocked(void *arg) } static void -uinput_ev_event(struct evdev_dev *evdev, void *softc, uint16_t type, - uint16_t code, int32_t value) +uinput_ev_event(struct evdev_dev *evdev, uint16_t type, uint16_t code, + int32_t value) { - struct uinput_cdev_state *state = softc; + struct uinput_cdev_state *state = evdev_get_softc(evdev); if (type == EV_LED) evdev_push_event(evdev, type, code, value); diff --git a/freebsd/sys/dev/fxp/if_fxp.c b/freebsd/sys/dev/fxp/if_fxp.c index ca933aa8..032246d8 100644 --- a/freebsd/sys/dev/fxp/if_fxp.c +++ b/freebsd/sys/dev/fxp/if_fxp.c @@ -309,6 +309,8 @@ static devclass_t fxp_devclass; DRIVER_MODULE_ORDERED(fxp, pci, fxp_driver, fxp_devclass, NULL, NULL, SI_ORDER_ANY); +MODULE_PNP_INFO("U16:vendor;U16:device", pci, fxp, fxp_ident_table, + sizeof(fxp_ident_table[0]), nitems(fxp_ident_table) - 1); DRIVER_MODULE(miibus, fxp, miibus_driver, miibus_devclass, NULL, NULL); static struct resource_spec fxp_res_spec_mem[] = { diff --git a/freebsd/sys/dev/kbd/kbd.c b/freebsd/sys/dev/kbd/kbd.c index c7512e89..b157e57e 100644 --- a/freebsd/sys/dev/kbd/kbd.c +++ b/freebsd/sys/dev/kbd/kbd.c @@ -49,6 +49,7 @@ __FBSDID("$FreeBSD$"); #include <sys/kbio.h> +#include <dev/evdev/input-event-codes.h> #include <dev/kbd/kbdreg.h> #define KBD_INDEX(dev) dev2unit(dev) @@ -1477,3 +1478,41 @@ genkbd_keyaction(keyboard_t *kbd, int keycode, int up, int *shiftstate, } /* NOT REACHED */ } + +void +kbd_ev_event(keyboard_t *kbd, uint16_t type, uint16_t code, int32_t value) +{ + int delay[2], led = 0, leds, oleds; + + if (type == EV_LED) { + leds = oleds = KBD_LED_VAL(kbd); + switch (code) { + case LED_CAPSL: + led = CLKED; + break; + case LED_NUML: + led = NLKED; + break; + case LED_SCROLLL: + led = SLKED; + break; + } + + if (value) + leds |= led; + else + leds &= ~led; + + if (leds != oleds) + kbdd_ioctl(kbd, KDSETLED, (caddr_t)&leds); + + } else if (type == EV_REP && code == REP_DELAY) { + delay[0] = value; + delay[1] = kbd->kb_delay2; + kbdd_ioctl(kbd, KDSETREPEAT, (caddr_t)delay); + } else if (type == EV_REP && code == REP_PERIOD) { + delay[0] = kbd->kb_delay1; + delay[1] = value; + kbdd_ioctl(kbd, KDSETREPEAT, (caddr_t)delay); + } +} diff --git a/freebsd/sys/dev/kbd/kbdreg.h b/freebsd/sys/dev/kbd/kbdreg.h index 5caafdda..07c4cfd9 100644 --- a/freebsd/sys/dev/kbd/kbdreg.h +++ b/freebsd/sys/dev/kbd/kbdreg.h @@ -253,6 +253,10 @@ keyboard_t *kbd_get_keyboard(int index); int kbd_configure(int flags); /* see `kb_config' above for flag bit definitions */ +/* evdev2kbd mappings */ +void kbd_ev_event(keyboard_t *kbd, uint16_t type, + uint16_t code, int32_t value); + #ifdef KBD_INSTALL_CDEV /* virtual keyboard cdev driver functions */ diff --git a/freebsd/sys/dev/mii/icsphy.c b/freebsd/sys/dev/mii/icsphy.c index bde90714..183814ae 100755 --- a/freebsd/sys/dev/mii/icsphy.c +++ b/freebsd/sys/dev/mii/icsphy.c @@ -115,9 +115,7 @@ static const struct mii_phydesc icsphys[] = { MII_PHY_DESC(ICS, 1890), MII_PHY_DESC(ICS, 1892), MII_PHY_DESC(ICS, 1893), -#ifdef __rtems__ MII_PHY_DESC(ICS, 1893C), -#endif /* __rtems__ */ MII_PHY_END }; diff --git a/freebsd/sys/dev/mmc/mmc.c b/freebsd/sys/dev/mmc/mmc.c index 2c3cba3d..cfbce2a5 100644 --- a/freebsd/sys/dev/mmc/mmc.c +++ b/freebsd/sys/dev/mmc/mmc.c @@ -1600,10 +1600,13 @@ mmc_discover_cards(struct mmc_softc *sc) uint32_t raw_cid[4]; struct mmc_ivars *ivar = NULL; const struct mmc_quirk *quirk; + const uint8_t *ext_csd; device_t child; int err, host_caps, i, newcard; uint32_t resp, sec_count, status; uint16_t rca = 2; + int16_t rev; + uint8_t card_type; host_caps = mmcbr_get_caps(sc->dev); if (bootverbose || mmc_debug) @@ -1791,6 +1794,7 @@ mmc_discover_cards(struct mmc_softc *sc) goto free_ivar; } + rev = -1; /* Only MMC >= 4.x devices support EXT_CSD. */ if (ivar->csd.spec_vers >= 4) { err = mmc_send_ext_csd(sc->dev, sc->dev, @@ -1800,11 +1804,10 @@ mmc_discover_cards(struct mmc_softc *sc) "Error reading EXT_CSD %d\n", err); goto free_ivar; } + ext_csd = ivar->raw_ext_csd; + rev = ext_csd[EXT_CSD_REV]; /* Handle extended capacity from EXT_CSD */ - sec_count = ivar->raw_ext_csd[EXT_CSD_SEC_CNT] + - (ivar->raw_ext_csd[EXT_CSD_SEC_CNT + 1] << 8) + - (ivar->raw_ext_csd[EXT_CSD_SEC_CNT + 2] << 16) + - (ivar->raw_ext_csd[EXT_CSD_SEC_CNT + 3] << 24); + sec_count = le32dec(&ext_csd[EXT_CSD_SEC_CNT]); if (sec_count != 0) { ivar->sec_count = sec_count; ivar->high_cap = 1; @@ -1812,65 +1815,56 @@ mmc_discover_cards(struct mmc_softc *sc) /* Find maximum supported bus width. */ ivar->bus_width = mmc_test_bus_width(sc); /* Get device speeds beyond normal mode. */ - if ((ivar->raw_ext_csd[EXT_CSD_CARD_TYPE] & - EXT_CSD_CARD_TYPE_HS_52) != 0) { + card_type = ext_csd[EXT_CSD_CARD_TYPE]; + if ((card_type & EXT_CSD_CARD_TYPE_HS_52) != 0) { setbit(&ivar->timings, bus_timing_hs); ivar->hs_tran_speed = MMC_TYPE_HS_52_MAX; - } else if ((ivar->raw_ext_csd[EXT_CSD_CARD_TYPE] & - EXT_CSD_CARD_TYPE_HS_26) != 0) { + } else if ((card_type & EXT_CSD_CARD_TYPE_HS_26) != 0) { setbit(&ivar->timings, bus_timing_hs); ivar->hs_tran_speed = MMC_TYPE_HS_26_MAX; } - if ((ivar->raw_ext_csd[EXT_CSD_CARD_TYPE] & - EXT_CSD_CARD_TYPE_DDR_52_1_2V) != 0 && + if ((card_type & EXT_CSD_CARD_TYPE_DDR_52_1_2V) != 0 && (host_caps & MMC_CAP_SIGNALING_120) != 0) { setbit(&ivar->timings, bus_timing_mmc_ddr52); setbit(&ivar->vccq_120, bus_timing_mmc_ddr52); } - if ((ivar->raw_ext_csd[EXT_CSD_CARD_TYPE] & - EXT_CSD_CARD_TYPE_DDR_52_1_8V) != 0 && + if ((card_type & EXT_CSD_CARD_TYPE_DDR_52_1_8V) != 0 && (host_caps & MMC_CAP_SIGNALING_180) != 0) { setbit(&ivar->timings, bus_timing_mmc_ddr52); setbit(&ivar->vccq_180, bus_timing_mmc_ddr52); } - if ((ivar->raw_ext_csd[EXT_CSD_CARD_TYPE] & - EXT_CSD_CARD_TYPE_HS200_1_2V) != 0 && + if ((card_type & EXT_CSD_CARD_TYPE_HS200_1_2V) != 0 && (host_caps & MMC_CAP_SIGNALING_120) != 0) { setbit(&ivar->timings, bus_timing_mmc_hs200); setbit(&ivar->vccq_120, bus_timing_mmc_hs200); } - if ((ivar->raw_ext_csd[EXT_CSD_CARD_TYPE] & - EXT_CSD_CARD_TYPE_HS200_1_8V) != 0 && + if ((card_type & EXT_CSD_CARD_TYPE_HS200_1_8V) != 0 && (host_caps & MMC_CAP_SIGNALING_180) != 0) { setbit(&ivar->timings, bus_timing_mmc_hs200); setbit(&ivar->vccq_180, bus_timing_mmc_hs200); } - if ((ivar->raw_ext_csd[EXT_CSD_CARD_TYPE] & - EXT_CSD_CARD_TYPE_HS400_1_2V) != 0 && + if ((card_type & EXT_CSD_CARD_TYPE_HS400_1_2V) != 0 && (host_caps & MMC_CAP_SIGNALING_120) != 0 && ivar->bus_width == bus_width_8) { setbit(&ivar->timings, bus_timing_mmc_hs400); setbit(&ivar->vccq_120, bus_timing_mmc_hs400); } - if ((ivar->raw_ext_csd[EXT_CSD_CARD_TYPE] & - EXT_CSD_CARD_TYPE_HS400_1_8V) != 0 && + if ((card_type & EXT_CSD_CARD_TYPE_HS400_1_8V) != 0 && (host_caps & MMC_CAP_SIGNALING_180) != 0 && ivar->bus_width == bus_width_8) { setbit(&ivar->timings, bus_timing_mmc_hs400); setbit(&ivar->vccq_180, bus_timing_mmc_hs400); } - if ((ivar->raw_ext_csd[EXT_CSD_CARD_TYPE] & - EXT_CSD_CARD_TYPE_HS400_1_2V) != 0 && - (ivar->raw_ext_csd[EXT_CSD_STROBE_SUPPORT] & + if ((card_type & EXT_CSD_CARD_TYPE_HS400_1_2V) != 0 && + (ext_csd[EXT_CSD_STROBE_SUPPORT] & EXT_CSD_STROBE_SUPPORT_EN) != 0 && (host_caps & MMC_CAP_SIGNALING_120) != 0 && ivar->bus_width == bus_width_8) { setbit(&ivar->timings, bus_timing_mmc_hs400es); setbit(&ivar->vccq_120, bus_timing_mmc_hs400es); } - if ((ivar->raw_ext_csd[EXT_CSD_CARD_TYPE] & - EXT_CSD_CARD_TYPE_HS400_1_8V) != 0 && - (ivar->raw_ext_csd[EXT_CSD_STROBE_SUPPORT] & + if ((card_type & EXT_CSD_CARD_TYPE_HS400_1_8V) != 0 && + (ext_csd[EXT_CSD_STROBE_SUPPORT] & EXT_CSD_STROBE_SUPPORT_EN) != 0 && (host_caps & MMC_CAP_SIGNALING_180) != 0 && ivar->bus_width == bus_width_8) { @@ -1882,13 +1876,13 @@ mmc_discover_cards(struct mmc_softc *sc) * units of 10 ms), defaulting to 500 ms. */ ivar->cmd6_time = 500 * 1000; - if (ivar->raw_ext_csd[EXT_CSD_REV] >= 6) + if (rev >= 6) ivar->cmd6_time = 10 * - ivar->raw_ext_csd[EXT_CSD_GEN_CMD6_TIME]; + ext_csd[EXT_CSD_GEN_CMD6_TIME]; /* Handle HC erase sector size. */ - if (ivar->raw_ext_csd[EXT_CSD_ERASE_GRP_SIZE] != 0) { + if (ext_csd[EXT_CSD_ERASE_GRP_SIZE] != 0) { ivar->erase_sector = 1024 * - ivar->raw_ext_csd[EXT_CSD_ERASE_GRP_SIZE]; + ext_csd[EXT_CSD_ERASE_GRP_SIZE]; err = mmc_switch(sc->dev, sc->dev, ivar->rca, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_ERASE_GRP_DEF, @@ -1903,8 +1897,7 @@ mmc_discover_cards(struct mmc_softc *sc) } } - mmc_decode_cid_mmc(ivar->raw_cid, &ivar->cid, - ivar->raw_ext_csd[EXT_CSD_REV] >= 5); + mmc_decode_cid_mmc(ivar->raw_cid, &ivar->cid, rev >= 5); child_common: for (quirk = &mmc_quirks[0]; quirk->mid != 0x0; quirk++) { diff --git a/freebsd/sys/dev/mmc/mmcbrvar.h b/freebsd/sys/dev/mmc/mmcbrvar.h index 6e4bec70..acddd3a3 100644 --- a/freebsd/sys/dev/mmc/mmcbrvar.h +++ b/freebsd/sys/dev/mmc/mmcbrvar.h @@ -97,7 +97,6 @@ MMCBR_ACCESSOR(host_ocr, HOST_OCR, int) MMCBR_ACCESSOR(mode, MODE, int) MMCBR_ACCESSOR(ocr, OCR, int) MMCBR_ACCESSOR(power_mode, POWER_MODE, int) -MMCBR_ACCESSOR(retune_req, RETUNE_REQ, int) MMCBR_ACCESSOR(vdd, VDD, int) MMCBR_ACCESSOR(vccq, VCCQ, int) MMCBR_ACCESSOR(caps, CAPS, int) @@ -106,6 +105,20 @@ MMCBR_ACCESSOR(max_data, MAX_DATA, int) MMCBR_ACCESSOR(max_busy_timeout, MAX_BUSY_TIMEOUT, u_int) static int __inline +mmcbr_get_retune_req(device_t dev) +{ + uintptr_t v; + + if (__predict_false(BUS_READ_IVAR(device_get_parent(dev), dev, + MMCBR_IVAR_RETUNE_REQ, &v) != 0)) + return (retune_req_none); + return ((int)v); +} + +/* + * Convenience wrappers for the mmcbr interface + */ +static int __inline mmcbr_update_ios(device_t dev) { diff --git a/freebsd/sys/dev/mmc/mmcsd.c b/freebsd/sys/dev/mmc/mmcsd.c index 263da55d..e469c1d5 100644 --- a/freebsd/sys/dev/mmc/mmcsd.c +++ b/freebsd/sys/dev/mmc/mmcsd.c @@ -63,6 +63,7 @@ __FBSDID("$FreeBSD$"); #include <sys/bio.h> #include <sys/bus.h> #include <sys/conf.h> +#include <sys/endian.h> #include <sys/fcntl.h> #include <sys/ioccom.h> #include <sys/kernel.h> @@ -477,7 +478,7 @@ mmcsd_attach(device_t dev) sc = device_get_softc(dev); sc->dev = dev; sc->mmcbus = mmcbus = device_get_parent(dev); - sc->mode = mmcbr_get_mode(mmcbus); + sc->mode = mmc_get_card_type(dev); /* * Note that in principle with an SDHCI-like re-tuning implementation, * the maximum data size can change at runtime due to a device removal/ @@ -542,10 +543,7 @@ mmcsd_attach(device_t dev) * 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; + size = le32dec(&ext_csd[EXT_CSD_CACHE_SIZE]); if (bootverbose) device_printf(dev, "cache size %juKB\n", size); if (size > 0) { @@ -591,10 +589,8 @@ mmcsd_attach(device_t dev) size *= erase_size * wp_size; if (size != mmc_get_media_size(dev) * sector_size) { sc->enh_size = size; - sc->enh_base = (ext_csd[EXT_CSD_ENH_START_ADDR] + - (ext_csd[EXT_CSD_ENH_START_ADDR + 1] << 8) + - (ext_csd[EXT_CSD_ENH_START_ADDR + 2] << 16) + - (ext_csd[EXT_CSD_ENH_START_ADDR + 3] << 24)) * + sc->enh_base = + le32dec(&ext_csd[EXT_CSD_ENH_START_ADDR]) * (sc->high_cap == 0 ? MMC_SECTOR_SIZE : 1); } else if (bootverbose) device_printf(dev, @@ -1578,7 +1574,7 @@ mmcsd_delete(struct mmcsd_part *part, struct bio *bp) memset(&cmd, 0, sizeof(cmd)); cmd.mrq = &req; req.cmd = &cmd; - if (mmc_get_card_type(dev) == mode_sd) + if (sc->mode == mode_sd) cmd.opcode = SD_ERASE_WR_BLK_START; else cmd.opcode = MMC_ERASE_GROUP_START; @@ -1597,7 +1593,7 @@ mmcsd_delete(struct mmcsd_part *part, struct bio *bp) memset(&req, 0, sizeof(req)); memset(&cmd, 0, sizeof(cmd)); req.cmd = &cmd; - if (mmc_get_card_type(dev) == mode_sd) + if (sc->mode == mode_sd) cmd.opcode = SD_ERASE_WR_BLK_END; else cmd.opcode = MMC_ERASE_GROUP_END; diff --git a/freebsd/sys/dev/nvme/nvme.h b/freebsd/sys/dev/nvme/nvme.h index 169f22d1..747767ce 100644 --- a/freebsd/sys/dev/nvme/nvme.h +++ b/freebsd/sys/dev/nvme/nvme.h @@ -110,13 +110,9 @@ /* Command field definitions */ -#define NVME_CMD_OPC_SHIFT (0) -#define NVME_CMD_OPC_MASK (0xFF) #define NVME_CMD_FUSE_SHIFT (8) #define NVME_CMD_FUSE_MASK (0x3) -#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) #define NVME_STATUS_SC_SHIFT (1) @@ -428,7 +424,8 @@ _Static_assert(sizeof(struct nvme_registers) == 0x1008, "bad size for nvme_regis struct nvme_command { /* dword 0 */ - uint16_t opc_fuse; /* opcode, fused operation */ + uint8_t opc; /* opcode */ + uint8_t fuse; /* fused operation */ uint16_t cid; /* command identifier */ /* dword 1 */ @@ -1288,7 +1285,7 @@ static inline void nvme_ns_flush_cmd(struct nvme_command *cmd, uint32_t nsid) { - cmd->opc_fuse = NVME_CMD_SET_OPC(NVME_OPC_FLUSH); + cmd->opc = NVME_OPC_FLUSH; cmd->nsid = htole32(nsid); } @@ -1296,7 +1293,7 @@ static inline void nvme_ns_rw_cmd(struct nvme_command *cmd, uint32_t rwcmd, uint32_t nsid, uint64_t lba, uint32_t count) { - cmd->opc_fuse = NVME_CMD_SET_OPC(rwcmd); + cmd->opc = rwcmd; cmd->nsid = htole32(nsid); cmd->cdw10 = htole32(lba & 0xffffffffu); cmd->cdw11 = htole32(lba >> 32); @@ -1321,7 +1318,7 @@ static inline void nvme_ns_trim_cmd(struct nvme_command *cmd, uint32_t nsid, uint32_t num_ranges) { - cmd->opc_fuse = NVME_CMD_SET_OPC(NVME_OPC_DATASET_MANAGEMENT); + cmd->opc = NVME_OPC_DATASET_MANAGEMENT; cmd->nsid = htole32(nsid); cmd->cdw10 = htole32(num_ranges - 1); cmd->cdw11 = htole32(NVME_DSM_ATTR_DEALLOCATE); diff --git a/freebsd/sys/dev/ofw/ofw_bus_subr.c b/freebsd/sys/dev/ofw/ofw_bus_subr.c index 5038bb03..5a76e555 100644 --- a/freebsd/sys/dev/ofw/ofw_bus_subr.c +++ b/freebsd/sys/dev/ofw/ofw_bus_subr.c @@ -93,6 +93,9 @@ ofw_bus_gen_child_pnpinfo_str(device_t cbdev, device_t child, char *buf, { *buf = '\0'; + if (!ofw_bus_status_okay(child)) + return (0); + if (ofw_bus_get_name(child) != NULL) { strlcat(buf, "name=", buflen); strlcat(buf, ofw_bus_get_name(child), buflen); @@ -102,6 +105,7 @@ ofw_bus_gen_child_pnpinfo_str(device_t cbdev, device_t child, char *buf, strlcat(buf, " compat=", buflen); strlcat(buf, ofw_bus_get_compat(child), buflen); } + return (0); }; diff --git a/freebsd/sys/dev/ofw/ofw_fdt.c b/freebsd/sys/dev/ofw/ofw_fdt.c index b1bbadee..d05a5dc1 100644 --- a/freebsd/sys/dev/ofw/ofw_fdt.c +++ b/freebsd/sys/dev/ofw/ofw_fdt.c @@ -287,8 +287,6 @@ ofw_fdt_getprop(ofw_t ofw, phandle_t package, const char *propname, void *buf, /* Emulate the 'name' property */ name = fdt_get_name(fdtp, offset, &len); strncpy(buf, name, buflen); - if (len + 1 > buflen) - len = buflen; return (len + 1); } @@ -307,9 +305,8 @@ ofw_fdt_getprop(ofw_t ofw, phandle_t package, const char *propname, void *buf, if (prop == NULL) return (-1); - if (len > buflen) - len = buflen; - bcopy(prop, buf, len); + bcopy(prop, buf, min(len, buflen)); + return (len); } diff --git a/freebsd/sys/dev/ofw/ofw_subr.c b/freebsd/sys/dev/ofw/ofw_subr.c index 8359485e..4a20727c 100644 --- a/freebsd/sys/dev/ofw/ofw_subr.c +++ b/freebsd/sys/dev/ofw/ofw_subr.c @@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$"); #include <sys/param.h> +#include <sys/boot.h> #include <sys/bus.h> #include <sys/libkern.h> #include <sys/reboot.h> @@ -63,7 +64,9 @@ get_addr_props(phandle_t node, uint32_t *addrp, uint32_t *sizep, int *pcip) res = OF_getprop(node, "device_type", type, sizeof(type)); if (res != -1) { type[sizeof(type) - 1] = '\0'; - pci = (strcmp(type, "pci") == 0) ? 1 : 0; + if (strcmp(type, "pci") == 0 || + strcmp(type, "pciex")== 0) + pci = 1; } } if (addrp != NULL) @@ -172,7 +175,7 @@ ofw_reg_to_paddr(phandle_t dev, int regno, bus_addr_t *paddr, } KASSERT(addr <= BUS_SPACE_MAXADDR, - ("Bus sddress is too large: %jx", (uintmax_t)addr)); + ("Bus address is too large: %jx", (uintmax_t)addr)); KASSERT(size <= BUS_SPACE_MAXSIZE, ("Bus size is too large: %jx", (uintmax_t)size)); @@ -184,44 +187,6 @@ ofw_reg_to_paddr(phandle_t dev, int regno, bus_addr_t *paddr, return (0); } -/* Parse cmd line args as env - copied from xlp_machdep. */ -/* XXX-BZ this should really be centrally provided for all (boot) code. */ -static void -_parse_bootargs(char *cmdline) -{ - char *n, *v; - - while ((v = strsep(&cmdline, " \n")) != NULL) { - if (*v == '\0') - continue; - if (*v == '-') { - while (*v != '\0') { - v++; - switch (*v) { - case 'a': boothowto |= RB_ASKNAME; break; - /* Someone should simulate that ;-) */ - case 'C': boothowto |= RB_CDROM; break; - case 'd': boothowto |= RB_KDB; break; - case 'D': boothowto |= RB_MULTIPLE; break; - case 'm': boothowto |= RB_MUTE; break; - case 'g': boothowto |= RB_GDB; break; - case 'h': boothowto |= RB_SERIAL; break; - case 'p': boothowto |= RB_PAUSE; break; - case 'r': boothowto |= RB_DFLTROOT; break; - case 's': boothowto |= RB_SINGLE; break; - case 'v': boothowto |= RB_VERBOSE; break; - } - } - } else { - n = strsep(&v, "="); - if (v == NULL) - kern_setenv(n, "1"); - else - kern_setenv(n, v); - } - } -} - /* * This is intended to be called early on, right after the OF system is * initialized, so pmap may not be up yet. @@ -238,7 +203,7 @@ ofw_parse_bootargs(void) return (chosen); if ((err = OF_getprop(chosen, "bootargs", buf, sizeof(buf))) != -1) { - _parse_bootargs(buf); + boothowto |= boot_parse_cmdline(buf); return (0); } diff --git a/freebsd/sys/dev/pci/pci.c b/freebsd/sys/dev/pci/pci.c index 55a21320..512e8636 100644 --- a/freebsd/sys/dev/pci/pci.c +++ b/freebsd/sys/dev/pci/pci.c @@ -401,6 +401,11 @@ static int pci_enable_ari = 1; SYSCTL_INT(_hw_pci, OID_AUTO, enable_ari, CTLFLAG_RDTUN, &pci_enable_ari, 0, "Enable support for PCIe Alternative RID Interpretation"); +static int pci_clear_aer_on_attach = 0; +SYSCTL_INT(_hw_pci, OID_AUTO, clear_aer_on_attach, CTLFLAG_RWTUN, + &pci_clear_aer_on_attach, 0, + "Clear port and device AER state on driver attach"); + static int pci_has_quirk(uint32_t devid, int quirk) { @@ -4214,17 +4219,98 @@ pci_create_iov_child_method(device_t bus, device_t pf, uint16_t rid, } #endif +static void +pci_add_child_clear_aer(device_t dev, struct pci_devinfo *dinfo) +{ + int aer; + uint32_t r; + uint16_t r2; + + if (dinfo->cfg.pcie.pcie_location != 0 && + dinfo->cfg.pcie.pcie_type == PCIEM_TYPE_ROOT_PORT) { + r2 = pci_read_config(dev, dinfo->cfg.pcie.pcie_location + + PCIER_ROOT_CTL, 2); + r2 &= ~(PCIEM_ROOT_CTL_SERR_CORR | + PCIEM_ROOT_CTL_SERR_NONFATAL | PCIEM_ROOT_CTL_SERR_FATAL); + pci_write_config(dev, dinfo->cfg.pcie.pcie_location + + PCIER_ROOT_CTL, r2, 2); + } + if (pci_find_extcap(dev, PCIZ_AER, &aer) == 0) { + r = pci_read_config(dev, aer + PCIR_AER_UC_STATUS, 4); + pci_write_config(dev, aer + PCIR_AER_UC_STATUS, r, 4); + if (r != 0 && bootverbose) { + pci_printf(&dinfo->cfg, + "clearing AER UC 0x%08x -> 0x%08x\n", + r, pci_read_config(dev, aer + PCIR_AER_UC_STATUS, + 4)); + } + + r = pci_read_config(dev, aer + PCIR_AER_UC_MASK, 4); + r &= ~(PCIM_AER_UC_TRAINING_ERROR | + PCIM_AER_UC_DL_PROTOCOL_ERROR | + PCIM_AER_UC_SURPRISE_LINK_DOWN | + PCIM_AER_UC_POISONED_TLP | + PCIM_AER_UC_FC_PROTOCOL_ERROR | + PCIM_AER_UC_COMPLETION_TIMEOUT | + PCIM_AER_UC_COMPLETER_ABORT | + PCIM_AER_UC_UNEXPECTED_COMPLETION | + PCIM_AER_UC_RECEIVER_OVERFLOW | + PCIM_AER_UC_MALFORMED_TLP | + PCIM_AER_UC_ECRC_ERROR | + PCIM_AER_UC_UNSUPPORTED_REQUEST | + PCIM_AER_UC_ACS_VIOLATION | + PCIM_AER_UC_INTERNAL_ERROR | + PCIM_AER_UC_MC_BLOCKED_TLP | + PCIM_AER_UC_ATOMIC_EGRESS_BLK | + PCIM_AER_UC_TLP_PREFIX_BLOCKED); + pci_write_config(dev, aer + PCIR_AER_UC_MASK, r, 4); + + r = pci_read_config(dev, aer + PCIR_AER_COR_STATUS, 4); + pci_write_config(dev, aer + PCIR_AER_COR_STATUS, r, 4); + if (r != 0 && bootverbose) { + pci_printf(&dinfo->cfg, + "clearing AER COR 0x%08x -> 0x%08x\n", + r, pci_read_config(dev, aer + PCIR_AER_COR_STATUS, + 4)); + } + + r = pci_read_config(dev, aer + PCIR_AER_COR_MASK, 4); + r &= ~(PCIM_AER_COR_RECEIVER_ERROR | + PCIM_AER_COR_BAD_TLP | + PCIM_AER_COR_BAD_DLLP | + PCIM_AER_COR_REPLAY_ROLLOVER | + PCIM_AER_COR_REPLAY_TIMEOUT | + PCIM_AER_COR_ADVISORY_NF_ERROR | + PCIM_AER_COR_INTERNAL_ERROR | + PCIM_AER_COR_HEADER_LOG_OVFLOW); + pci_write_config(dev, aer + PCIR_AER_COR_MASK, r, 4); + + r = pci_read_config(dev, dinfo->cfg.pcie.pcie_location + + PCIER_DEVICE_CTL, 2); + r |= PCIEM_CTL_COR_ENABLE | PCIEM_CTL_NFER_ENABLE | + PCIEM_CTL_FER_ENABLE | PCIEM_CTL_URR_ENABLE; + pci_write_config(dev, dinfo->cfg.pcie.pcie_location + + PCIER_DEVICE_CTL, r, 2); + } +} + void pci_add_child(device_t bus, struct pci_devinfo *dinfo) { - dinfo->cfg.dev = device_add_child(bus, NULL, -1); - device_set_ivars(dinfo->cfg.dev, dinfo); + device_t dev; + + dinfo->cfg.dev = dev = device_add_child(bus, NULL, -1); + device_set_ivars(dev, dinfo); resource_list_init(&dinfo->resources); - pci_cfg_save(dinfo->cfg.dev, dinfo, 0); - pci_cfg_restore(dinfo->cfg.dev, dinfo); + pci_cfg_save(dev, dinfo, 0); + pci_cfg_restore(dev, dinfo); pci_print_verbose(dinfo); - pci_add_resources(bus, dinfo->cfg.dev, 0, 0); + pci_add_resources(bus, dev, 0, 0); pci_child_added(dinfo->cfg.dev); + + if (pci_clear_aer_on_attach) + pci_add_child_clear_aer(dev, dinfo); + EVENTHANDLER_INVOKE(pci_add_device, dinfo->cfg.dev); } @@ -6263,3 +6349,164 @@ pcie_flr(device_t dev, u_int max_delay, bool force) pci_printf(&dinfo->cfg, "Transactions pending after FLR!\n"); return (true); } + +const struct pci_device_table * +pci_match_device(device_t child, const struct pci_device_table *id, size_t nelt) +{ + bool match; + uint16_t vendor, device, subvendor, subdevice, class, subclass, revid; + + vendor = pci_get_vendor(child); + device = pci_get_device(child); + subvendor = pci_get_subvendor(child); + subdevice = pci_get_subdevice(child); + class = pci_get_class(child); + subclass = pci_get_subclass(child); + revid = pci_get_revid(child); + while (nelt-- > 0) { + match = true; + if (id->match_flag_vendor) + match &= vendor == id->vendor; + if (id->match_flag_device) + match &= device == id->device; + if (id->match_flag_subvendor) + match &= subvendor == id->subvendor; + if (id->match_flag_subdevice) + match &= subdevice == id->subdevice; + if (id->match_flag_class) + match &= class == id->class_id; + if (id->match_flag_subclass) + match &= subclass == id->subclass; + if (id->match_flag_revid) + match &= revid == id->revid; + if (match) + return (id); + id++; + } + return (NULL); +} + +static void +pci_print_faulted_dev_name(const struct pci_devinfo *dinfo) +{ + const char *dev_name; + device_t dev; + + dev = dinfo->cfg.dev; + printf("pci%d:%d:%d:%d", dinfo->cfg.domain, dinfo->cfg.bus, + dinfo->cfg.slot, dinfo->cfg.func); + dev_name = device_get_name(dev); + if (dev_name != NULL) + printf(" (%s%d)", dev_name, device_get_unit(dev)); +} + +void +pci_print_faulted_dev(void) +{ + struct pci_devinfo *dinfo; + device_t dev; + int aer, i; + uint32_t r1, r2; + uint16_t status; + + STAILQ_FOREACH(dinfo, &pci_devq, pci_links) { + dev = dinfo->cfg.dev; + status = pci_read_config(dev, PCIR_STATUS, 2); + status &= PCIM_STATUS_MDPERR | PCIM_STATUS_STABORT | + PCIM_STATUS_RTABORT | PCIM_STATUS_RMABORT | + PCIM_STATUS_SERR | PCIM_STATUS_PERR; + if (status != 0) { + pci_print_faulted_dev_name(dinfo); + printf(" error 0x%04x\n", status); + } + if (dinfo->cfg.pcie.pcie_location != 0) { + status = pci_read_config(dev, + dinfo->cfg.pcie.pcie_location + + PCIER_DEVICE_STA, 2); + if ((status & (PCIEM_STA_CORRECTABLE_ERROR | + PCIEM_STA_NON_FATAL_ERROR | PCIEM_STA_FATAL_ERROR | + PCIEM_STA_UNSUPPORTED_REQ)) != 0) { + pci_print_faulted_dev_name(dinfo); + printf(" PCIe DEVCTL 0x%04x DEVSTA 0x%04x\n", + pci_read_config(dev, + dinfo->cfg.pcie.pcie_location + + PCIER_DEVICE_CTL, 2), + status); + } + } + if (pci_find_extcap(dev, PCIZ_AER, &aer) == 0) { + r1 = pci_read_config(dev, aer + PCIR_AER_UC_STATUS, 4); + r2 = pci_read_config(dev, aer + PCIR_AER_COR_STATUS, 4); + if (r1 != 0 || r2 != 0) { + pci_print_faulted_dev_name(dinfo); + printf(" AER UC 0x%08x Mask 0x%08x Svr 0x%08x\n" + " COR 0x%08x Mask 0x%08x Ctl 0x%08x\n", + r1, pci_read_config(dev, aer + + PCIR_AER_UC_MASK, 4), + pci_read_config(dev, aer + + PCIR_AER_UC_SEVERITY, 4), + r2, pci_read_config(dev, aer + + PCIR_AER_COR_MASK, 4), + pci_read_config(dev, aer + + PCIR_AER_CAP_CONTROL, 4)); + for (i = 0; i < 4; i++) { + r1 = pci_read_config(dev, aer + + PCIR_AER_HEADER_LOG + i * 4, 4); + printf(" HL%d: 0x%08x\n", i, r1); + } + } + } + } +} + +#ifdef DDB +DB_SHOW_COMMAND(pcierr, pci_print_faulted_dev_db) +{ + + pci_print_faulted_dev(); +} + +static void +db_clear_pcie_errors(const struct pci_devinfo *dinfo) +{ + device_t dev; + int aer; + uint32_t r; + + dev = dinfo->cfg.dev; + r = pci_read_config(dev, dinfo->cfg.pcie.pcie_location + + PCIER_DEVICE_STA, 2); + pci_write_config(dev, dinfo->cfg.pcie.pcie_location + + PCIER_DEVICE_STA, r, 2); + + if (pci_find_extcap(dev, PCIZ_AER, &aer) != 0) + return; + r = pci_read_config(dev, aer + PCIR_AER_UC_STATUS, 4); + if (r != 0) + pci_write_config(dev, aer + PCIR_AER_UC_STATUS, r, 4); + r = pci_read_config(dev, aer + PCIR_AER_COR_STATUS, 4); + if (r != 0) + pci_write_config(dev, aer + PCIR_AER_COR_STATUS, r, 4); +} + +DB_COMMAND(pci_clearerr, db_pci_clearerr) +{ + struct pci_devinfo *dinfo; + device_t dev; + uint16_t status, status1; + + STAILQ_FOREACH(dinfo, &pci_devq, pci_links) { + dev = dinfo->cfg.dev; + status1 = status = pci_read_config(dev, PCIR_STATUS, 2); + status1 &= PCIM_STATUS_MDPERR | PCIM_STATUS_STABORT | + PCIM_STATUS_RTABORT | PCIM_STATUS_RMABORT | + PCIM_STATUS_SERR | PCIM_STATUS_PERR; + if (status1 != 0) { + status &= ~status1; + pci_write_config(dev, PCIR_STATUS, status, 2); + } + if (dinfo->cfg.pcie.pcie_location != 0) + db_clear_pcie_errors(dinfo); + } +} +#endif diff --git a/freebsd/sys/dev/pci/pci_user.c b/freebsd/sys/dev/pci/pci_user.c index c9d500a8..b3a2e9e2 100644 --- a/freebsd/sys/dev/pci/pci_user.c +++ b/freebsd/sys/dev/pci/pci_user.c @@ -33,6 +33,7 @@ __FBSDID("$FreeBSD$"); #include <rtems/bsd/local/opt_bus.h> /* XXX trim includes */ +#include <sys/types.h> #include <sys/param.h> #include <sys/systm.h> #include <sys/malloc.h> @@ -41,13 +42,19 @@ __FBSDID("$FreeBSD$"); #include <sys/fcntl.h> #include <sys/conf.h> #include <sys/kernel.h> +#include <sys/mman.h> #include <sys/proc.h> #include <sys/queue.h> -#include <sys/types.h> +#include <sys/rwlock.h> +#include <sys/sglist.h> #include <vm/vm.h> #include <vm/pmap.h> #include <vm/vm_extern.h> +#include <vm/vm_map.h> +#include <vm/vm_object.h> +#include <vm/vm_page.h> +#include <vm/vm_pager.h> #include <sys/bus.h> #include <machine/bus.h> @@ -441,6 +448,14 @@ pci_conf_match(u_long cmd, struct pci_match_conf *matches, int num_matches, } } +/* + * Like PVE_NEXT but takes an explicit length since 'pve' is a user + * pointer that cannot be dereferenced. + */ +#define PVE_NEXT_LEN(pve, datalen) \ + ((struct pci_vpd_element *)((char *)(pve) + \ + sizeof(struct pci_vpd_element) + (datalen))) + static int pci_list_vpd(device_t dev, struct pci_list_vpd_io *lvio) { @@ -489,7 +504,7 @@ pci_list_vpd(device_t dev, struct pci_list_vpd_io *lvio) strlen(vpd->vpd_ident)); if (error) return (error); - vpd_user = PVE_NEXT(vpd_user); + vpd_user = PVE_NEXT_LEN(vpd_user, vpd_element.pve_datalen); vpd_element.pve_flags = 0; for (i = 0; i < vpd->vpd_rocnt; i++) { vpd_element.pve_keyword[0] = vpd->vpd_ros[i].keyword[0]; @@ -502,7 +517,7 @@ pci_list_vpd(device_t dev, struct pci_list_vpd_io *lvio) vpd->vpd_ros[i].len); if (error) return (error); - vpd_user = PVE_NEXT(vpd_user); + vpd_user = PVE_NEXT_LEN(vpd_user, vpd_element.pve_datalen); } vpd_element.pve_flags = PVE_FLAG_RW; for (i = 0; i < vpd->vpd_wcnt; i++) { @@ -516,7 +531,7 @@ pci_list_vpd(device_t dev, struct pci_list_vpd_io *lvio) vpd->vpd_w[i].len); if (error) return (error); - vpd_user = PVE_NEXT(vpd_user); + vpd_user = PVE_NEXT_LEN(vpd_user, vpd_element.pve_datalen); } KASSERT((char *)vpd_user - (char *)lvio->plvi_data == len, ("length mismatch")); @@ -698,6 +713,79 @@ pci_conf_for_copyout(const struct pci_conf *pcp, union pci_conf_union *pcup, } } +#ifndef __rtems__ +static int +pci_bar_mmap(device_t pcidev, struct pci_bar_mmap *pbm) +{ + vm_map_t map; + vm_object_t obj; + struct thread *td; + struct sglist *sg; + struct pci_map *pm; + vm_paddr_t pbase; + vm_size_t plen; + vm_offset_t addr; + vm_prot_t prot; + int error, flags; + + td = curthread; + map = &td->td_proc->p_vmspace->vm_map; + if ((pbm->pbm_flags & ~(PCIIO_BAR_MMAP_FIXED | PCIIO_BAR_MMAP_EXCL | + PCIIO_BAR_MMAP_RW | PCIIO_BAR_MMAP_ACTIVATE)) != 0 || + pbm->pbm_memattr != (vm_memattr_t)pbm->pbm_memattr || + !pmap_is_valid_memattr(map->pmap, pbm->pbm_memattr)) + return (EINVAL); + + /* Fetch the BAR physical base and length. */ + pm = pci_find_bar(pcidev, pbm->pbm_reg); + if (pm == NULL) + return (EINVAL); + if (!pci_bar_enabled(pcidev, pm)) + return (EBUSY); /* XXXKIB enable if _ACTIVATE */ + if (!PCI_BAR_MEM(pm->pm_value)) + return (EIO); + pbase = trunc_page(pm->pm_value); + plen = round_page(pm->pm_value + ((pci_addr_t)1 << pm->pm_size)) - + pbase; + prot = VM_PROT_READ | (((pbm->pbm_flags & PCIIO_BAR_MMAP_RW) != 0) ? + VM_PROT_WRITE : 0); + + /* Create vm structures and mmap. */ + sg = sglist_alloc(1, M_WAITOK); + error = sglist_append_phys(sg, pbase, plen); + if (error != 0) + goto out; + obj = vm_pager_allocate(OBJT_SG, sg, plen, prot, 0, td->td_ucred); + if (obj == NULL) { + error = EIO; + goto out; + } + obj->memattr = pbm->pbm_memattr; + flags = MAP_SHARED; + addr = 0; + if ((pbm->pbm_flags & PCIIO_BAR_MMAP_FIXED) != 0) { + addr = (uintptr_t)pbm->pbm_map_base; + flags |= MAP_FIXED; + } + if ((pbm->pbm_flags & PCIIO_BAR_MMAP_EXCL) != 0) + flags |= MAP_CHECK_EXCL; + error = vm_mmap_object(map, &addr, plen, prot, prot, flags, obj, 0, + FALSE, td); + if (error != 0) { + vm_object_deallocate(obj); + goto out; + } + pbm->pbm_map_base = (void *)addr; + pbm->pbm_map_length = plen; + pbm->pbm_bar_off = pm->pm_value - pbase; + pbm->pbm_bar_length = (pci_addr_t)1 << pm->pm_size; + +out: + sglist_free(sg); + return (error); +} +#endif /* __rtems__ */ + static int pci_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td) { @@ -711,6 +799,9 @@ 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; +#ifndef __rtems__ + struct pci_bar_mmap *pbm; +#endif /* __rtems__ */ size_t confsz, iolen; int error, ionum, i, num_patterns; union pci_conf_union pcu; @@ -1055,6 +1146,20 @@ getconfexit: } error = pci_list_vpd(pcidev, lvio); break; + +#ifndef __rtems__ + case PCIOCBARMMAP: + pbm = (struct pci_bar_mmap *)data; + if ((flag & FWRITE) == 0 && + (pbm->pbm_flags & PCIIO_BAR_MMAP_RW) != 0) + return (EPERM); + pcidev = pci_find_dbsf(pbm->pbm_sel.pc_domain, + pbm->pbm_sel.pc_bus, pbm->pbm_sel.pc_dev, + pbm->pbm_sel.pc_func); + error = pcidev == NULL ? ENODEV : pci_bar_mmap(pcidev, pbm); + break; +#endif /* __rtems__ */ + default: error = ENOTTY; break; diff --git a/freebsd/sys/dev/pci/pcivar.h b/freebsd/sys/dev/pci/pcivar.h index 492b7117..21d9bd03 100644 --- a/freebsd/sys/dev/pci/pcivar.h +++ b/freebsd/sys/dev/pci/pcivar.h @@ -259,6 +259,66 @@ typedef struct { extern uint32_t pci_numdevs; +struct pci_device_table { +#if BYTE_ORDER == LITTLE_ENDIAN + uint16_t + match_flag_vendor:1, + match_flag_device:1, + match_flag_subvendor:1, + match_flag_subdevice:1, + match_flag_class:1, + match_flag_subclass:1, + match_flag_revid:1, + match_flag_unused:9; +#else + uint16_t + match_flag_unused:9, + match_flag_revid:1, + match_flag_subclass:1, + match_flag_class:1, + match_flag_subdevice:1, + match_flag_subvendor:1, + match_flag_device:1, + match_flag_vendor:1; +#endif + uint16_t vendor; + uint16_t device; + uint16_t subvendor; + uint16_t subdevice; + uint16_t class_id; + uint16_t subclass; + uint16_t revid; + uint16_t unused; + uintptr_t driver_data; + char *descr; +}; + +#define PCI_DEV(v, d) \ + .match_flag_vendor = 1, .vendor = (v), \ + .match_flag_device = 1, .device = (d) +#define PCI_SUBDEV(sv, sd) \ + .match_flag_subvendor = 1, .subvendor = (sv), \ + .match_flag_subdevice = 1, .subdevice = (sd) +#define PCI_CLASS(x) \ + .match_flag_class = 1, .class_id = (x) +#define PCI_SUBCLASS(x) \ + .match_flag_subclass = 1, .subclass = (x) +#define PCI_REVID(x) \ + .match_flag_revid = 1, .revid = (x) +#define PCI_DESCR(x) \ + .descr = (x) +#define PCI_PNP_STR \ + "M16:mask;U16:vendor;U16:device;U16:subvendor;U16:subdevice;" \ + "U16:class;U16:subclass;U16:revid;" +#define PCI_PNP_INFO(table) \ + MODULE_PNP_INFO(PCI_PNP_STR, pci, table, table, sizeof(table[0]), \ + sizeof(table) / sizeof(table[0])) + +const struct pci_device_table *pci_match_device(device_t child, + const struct pci_device_table *id, size_t nelt); +#define PCI_MATCH(child, table) \ + pci_match_device(child, (table), nitems(table)); + /* Only if the prerequisites are present */ #if defined(_SYS_BUS_H_) && defined(_SYS_PCIIO_H_) struct pci_devinfo { @@ -416,7 +476,7 @@ pci_get_vpd_readonly(device_t dev, const char *kw, const char **vptr) static __inline int pci_is_vga_ioport_range(rman_res_t start, rman_res_t end) { - + return (((start >= 0x3b0 && end <= 0x3bb) || (start >= 0x3c0 && end <= 0x3df)) ? 1 : 0); } @@ -622,6 +682,8 @@ bool pcie_flr(device_t dev, u_int max_delay, bool force); int pcie_get_max_completion_timeout(device_t dev); bool pcie_wait_for_pending_transactions(device_t dev, u_int max_delay); +void pci_print_faulted_dev(void); + #ifdef BUS_SPACE_MAXADDR #if (BUS_SPACE_MAXADDR > 0xFFFFFFFF) #define PCI_DMA_BOUNDARY 0x100000000 diff --git a/freebsd/sys/dev/rtwn/rtl8812a/r12a_reg.h b/freebsd/sys/dev/rtwn/rtl8812a/r12a_reg.h index 41cc160f..581e7078 100644 --- a/freebsd/sys/dev/rtwn/rtl8812a/r12a_reg.h +++ b/freebsd/sys/dev/rtwn/rtl8812a/r12a_reg.h @@ -58,6 +58,16 @@ /* Bits for R92C_LEDCFG2. */ #define R12A_LEDCFG2_ENA 0x20 +/* Bits for R12A_RXDMA_PRO. */ +#define R12A_DMA_MODE 0x02 +#define R12A_BURST_CNT_M 0x0c +#define R12A_BURST_CNT_S 2 +#define R12A_BURST_SZ_M 0x30 +#define R12A_BURST_SZ_S 4 +#define R12A_BURST_SZ_USB3 0 +#define R12A_BURST_SZ_USB2 1 +#define R12A_BURST_SZ_USB1 2 + /* Bits for R12A_CCK_CHECK. */ #define R12A_CCK_CHECK_BCN1 0x20 #define R12A_CCK_CHECK_5GHZ 0x80 diff --git a/freebsd/sys/dev/rtwn/rtl8812a/usb/r12au.h b/freebsd/sys/dev/rtwn/rtl8812a/usb/r12au.h index 55d132c7..1ea08a2d 100644 --- a/freebsd/sys/dev/rtwn/rtl8812a/usb/r12au.h +++ b/freebsd/sys/dev/rtwn/rtl8812a/usb/r12au.h @@ -37,6 +37,7 @@ */ /* r12au_init.c */ void r12au_init_rx_agg(struct rtwn_softc *); +void r12au_init_burstlen_usb2(struct rtwn_softc *); void r12au_init_burstlen(struct rtwn_softc *); void r12au_init_ampdu_fwhw(struct rtwn_softc *); void r12au_init_ampdu(struct rtwn_softc *); diff --git a/freebsd/sys/dev/rtwn/rtl8812a/usb/r12au_init.c b/freebsd/sys/dev/rtwn/rtl8812a/usb/r12au_init.c index 29016424..26a83ce9 100644 --- a/freebsd/sys/dev/rtwn/rtl8812a/usb/r12au_init.c +++ b/freebsd/sys/dev/rtwn/rtl8812a/usb/r12au_init.c @@ -74,19 +74,32 @@ r12au_init_rx_agg(struct rtwn_softc *sc) } void +r12au_init_burstlen_usb2(struct rtwn_softc *sc) +{ + const uint8_t dma_count = R12A_DMA_MODE | SM(R12A_BURST_CNT, 3); + + if ((rtwn_read_1(sc, R92C_USB_INFO) & 0x30) == 0) { + /* Set burst packet length to 512 B. */ + rtwn_setbits_1(sc, R12A_RXDMA_PRO, R12A_BURST_SZ_M, + dma_count | SM(R12A_BURST_SZ, R12A_BURST_SZ_USB2)); + } else { + /* Set burst packet length to 64 B. */ + rtwn_setbits_1(sc, R12A_RXDMA_PRO, R12A_BURST_SZ_M, + dma_count | SM(R12A_BURST_SZ, R12A_BURST_SZ_USB1)); + } +} + +void r12au_init_burstlen(struct rtwn_softc *sc) { - if (rtwn_read_1(sc, R92C_TYPE_ID + 3) & 0x80) { - if ((rtwn_read_1(sc, R92C_USB_INFO) & 0x30) == 0) { - /* Set burst packet length to 512 B. */ - rtwn_setbits_1(sc, R12A_RXDMA_PRO, 0x20, 0x1e); - } else { - /* Set burst packet length to 64 B. */ - rtwn_setbits_1(sc, R12A_RXDMA_PRO, 0x10, 0x2e); - } - } else { /* USB 3.0 */ + const uint8_t dma_count = R12A_DMA_MODE | SM(R12A_BURST_CNT, 3); + + if (rtwn_read_1(sc, R92C_TYPE_ID + 3) & 0x80) + r12au_init_burstlen_usb2(sc); + else { /* USB 3.0 */ /* Set burst packet length to 1 KB. */ - rtwn_setbits_1(sc, R12A_RXDMA_PRO, 0x30, 0x0e); + rtwn_setbits_1(sc, R12A_RXDMA_PRO, R12A_BURST_SZ_M, + dma_count | SM(R12A_BURST_SZ, R12A_BURST_SZ_USB3)); rtwn_setbits_1(sc, 0xf008, 0x18, 0); } diff --git a/freebsd/sys/dev/rtwn/rtl8821a/usb/r21au.h b/freebsd/sys/dev/rtwn/rtl8821a/usb/r21au.h index 60aa476c..a327d2ad 100644 --- a/freebsd/sys/dev/rtwn/rtl8821a/usb/r21au.h +++ b/freebsd/sys/dev/rtwn/rtl8821a/usb/r21au.h @@ -37,7 +37,6 @@ */ /* r21au_init.c */ void r21au_init_tx_agg(struct rtwn_softc *); -void r21au_init_burstlen(struct rtwn_softc *); /* r21au_dfs.c */ void r21au_chan_check(void *, int); diff --git a/freebsd/sys/dev/rtwn/rtl8821a/usb/r21au_attach.c b/freebsd/sys/dev/rtwn/rtl8821a/usb/r21au_attach.c index 5cf721c2..976582ae 100644 --- a/freebsd/sys/dev/rtwn/rtl8821a/usb/r21au_attach.c +++ b/freebsd/sys/dev/rtwn/rtl8821a/usb/r21au_attach.c @@ -137,7 +137,7 @@ r21a_attach_private(struct rtwn_softc *sc) rs->rs_fix_spur = rtwn_nop_softc_chan; rs->rs_set_band_2ghz = r21a_set_band_2ghz; rs->rs_set_band_5ghz = r21a_set_band_5ghz; - rs->rs_init_burstlen = r21au_init_burstlen; + rs->rs_init_burstlen = r12au_init_burstlen_usb2; rs->rs_init_ampdu_fwhw = r21a_init_ampdu_fwhw; rs->rs_crystalcap_write = r21a_crystalcap_write; #ifndef RTWN_WITHOUT_UCODE diff --git a/freebsd/sys/dev/rtwn/rtl8821a/usb/r21au_init.c b/freebsd/sys/dev/rtwn/rtl8821a/usb/r21au_init.c index 31366e59..838e1b50 100644 --- a/freebsd/sys/dev/rtwn/rtl8821a/usb/r21au_init.c +++ b/freebsd/sys/dev/rtwn/rtl8821a/usb/r21au_init.c @@ -72,14 +72,3 @@ r21au_init_tx_agg(struct rtwn_softc *sc) rtwn_write_1(sc, R21A_DWBCN1_CTRL, uc->tx_agg_desc_num << 1); } -void -r21au_init_burstlen(struct rtwn_softc *sc) -{ - if ((rtwn_read_1(sc, R92C_USB_INFO) & 0x30) == 0) { - /* Set burst packet length to 512 B. */ - rtwn_setbits_1(sc, R12A_RXDMA_PRO, 0x20, 0x1e); - } else { - /* Set burst packet length to 64 B. */ - rtwn_setbits_1(sc, R12A_RXDMA_PRO, 0x10, 0x2e); - } -} diff --git a/freebsd/sys/dev/sdhci/sdhci.c b/freebsd/sys/dev/sdhci/sdhci.c index 39b9dc91..ccbf5d85 100644 --- a/freebsd/sys/dev/sdhci/sdhci.c +++ b/freebsd/sys/dev/sdhci/sdhci.c @@ -92,27 +92,49 @@ SYSCTL_INT(_hw_sdhci, OID_AUTO, quirk_set, CTLFLAG_RWTUN, &sdhci_quirk_set, 0, #define WR_MULTI_4(slot, off, ptr, count) \ SDHCI_WRITE_MULTI_4((slot)->bus, (slot), (off), (ptr), (count)) +static void sdhci_acmd_irq(struct sdhci_slot *slot, uint16_t acmd_err); static void sdhci_card_poll(void *arg); static void sdhci_card_task(void *arg, int pending); +static void sdhci_cmd_irq(struct sdhci_slot *slot, uint32_t intmask); +static void sdhci_data_irq(struct sdhci_slot *slot, uint32_t intmask); static int sdhci_exec_tuning(struct sdhci_slot *slot, bool reset); +static void sdhci_handle_card_present_locked(struct sdhci_slot *slot, + bool is_present); +static void sdhci_finish_command(struct sdhci_slot *slot); +static void sdhci_init(struct sdhci_slot *slot); +static void sdhci_read_block_pio(struct sdhci_slot *slot); +static void sdhci_req_done(struct sdhci_slot *slot); static void sdhci_req_wakeup(struct mmc_request *req); +static void sdhci_reset(struct sdhci_slot *slot, uint8_t mask); static void sdhci_retune(void *arg); static void sdhci_set_clock(struct sdhci_slot *slot, uint32_t clock); +static void sdhci_set_power(struct sdhci_slot *slot, u_char power); +static void sdhci_set_transfer_mode(struct sdhci_slot *slot, + struct mmc_data *data); static void sdhci_start(struct sdhci_slot *slot); +static void sdhci_timeout(void *arg); +static void sdhci_start_command(struct sdhci_slot *slot, + struct mmc_command *cmd); static void sdhci_start_data(struct sdhci_slot *slot, struct mmc_data *data); +static void sdhci_write_block_pio(struct sdhci_slot *slot); +static void sdhci_transfer_pio(struct sdhci_slot *slot); #ifdef MMCCAM /* CAM-related */ -int sdhci_cam_get_possible_host_clock(struct sdhci_slot *slot, int proposed_clock); -static int sdhci_cam_update_ios(struct sdhci_slot *slot); -static int sdhci_cam_request(struct sdhci_slot *slot, union ccb *ccb); static void sdhci_cam_action(struct cam_sim *sim, union ccb *ccb); +static int sdhci_cam_get_possible_host_clock(struct sdhci_slot *slot, + int proposed_clock); +static void sdhci_cam_handle_mmcio(struct cam_sim *sim, union ccb *ccb); static void sdhci_cam_poll(struct cam_sim *sim); +static int sdhci_cam_request(struct sdhci_slot *slot, union ccb *ccb); static int sdhci_cam_settran_settings(struct sdhci_slot *slot, union ccb *ccb); +static int sdhci_cam_update_ios(struct sdhci_slot *slot); #endif /* helper routines */ static void sdhci_dumpregs(struct sdhci_slot *slot); +static void sdhci_getaddr(void *arg, bus_dma_segment_t *segs, int nsegs, + int error); static int slot_printf(struct sdhci_slot *slot, const char * fmt, ...) __printflike(2, 3); static uint32_t sdhci_tuning_intmask(struct sdhci_slot *slot); @@ -1562,20 +1584,19 @@ sdhci_set_transfer_mode(struct sdhci_slot *slot, struct mmc_data *data) return; mode = SDHCI_TRNS_BLK_CNT_EN; - if (data->len > 512) + if (data->len > 512) { mode |= SDHCI_TRNS_MULTI; - if (data->flags & MMC_DATA_READ) - mode |= SDHCI_TRNS_READ; + if (__predict_true( #ifdef MMCCAM - struct ccb_mmcio *mmcio; - mmcio = &slot->ccb->mmcio; - if (mmcio->stop.opcode == MMC_STOP_TRANSMISSION - && !(slot->quirks & SDHCI_QUIRK_BROKEN_AUTO_STOP)) - mode |= SDHCI_TRNS_ACMD12; + slot->ccb->mmcio.stop.opcode == MMC_STOP_TRANSMISSION && #else - if (slot->req->stop && !(slot->quirks & SDHCI_QUIRK_BROKEN_AUTO_STOP)) - mode |= SDHCI_TRNS_ACMD12; + slot->req->stop != NULL && #endif + !(slot->quirks & SDHCI_QUIRK_BROKEN_AUTO_STOP))) + mode |= SDHCI_TRNS_ACMD12; + } + if (data->flags & MMC_DATA_READ) + mode |= SDHCI_TRNS_READ; if (slot->flags & SDHCI_USE_DMA) mode |= SDHCI_TRNS_DMA; @@ -2158,18 +2179,16 @@ done: } static void -sdhci_acmd_irq(struct sdhci_slot *slot) +sdhci_acmd_irq(struct sdhci_slot *slot, uint16_t acmd_err) { - uint16_t err; - err = RD4(slot, SDHCI_ACMD12_ERR); if (!slot->curcmd) { slot_printf(slot, "Got AutoCMD12 error 0x%04x, but " - "there is no active command.\n", err); + "there is no active command.\n", acmd_err); sdhci_dumpregs(slot); return; } - slot_printf(slot, "Got AutoCMD12 error 0x%04x\n", err); + slot_printf(slot, "Got AutoCMD12 error 0x%04x\n", acmd_err); sdhci_reset(slot, SDHCI_RESET_CMD); } @@ -2177,6 +2196,7 @@ void sdhci_generic_intr(struct sdhci_slot *slot) { uint32_t intmask, present; + uint16_t val16; SDHCI_LOCK(slot); /* Read slot interrupt status. */ @@ -2190,6 +2210,7 @@ sdhci_generic_intr(struct sdhci_slot *slot) /* Handle tuning error interrupt. */ if (__predict_false(intmask & SDHCI_INT_TUNEERR)) { + WR4(slot, SDHCI_INT_STATUS, SDHCI_INT_TUNEERR); slot_printf(slot, "Tuning error indicated\n"); slot->retune_req |= SDHCI_RETUNE_REQ_RESET; if (slot->curcmd) { @@ -2227,8 +2248,10 @@ sdhci_generic_intr(struct sdhci_slot *slot) } /* Handle AutoCMD12 error interrupt. */ if (intmask & SDHCI_INT_ACMD12ERR) { + /* Clearing SDHCI_INT_ACMD12ERR may clear SDHCI_ACMD12_ERR. */ + val16 = RD2(slot, SDHCI_ACMD12_ERR); WR4(slot, SDHCI_INT_STATUS, SDHCI_INT_ACMD12ERR); - sdhci_acmd_irq(slot); + sdhci_acmd_irq(slot, val16); } /* Handle bus power interrupt. */ if (intmask & SDHCI_INT_BUS_POWER) { @@ -2574,7 +2597,9 @@ sdhci_cam_poll(struct cam_sim *sim) return; } -int sdhci_cam_get_possible_host_clock(struct sdhci_slot *slot, int proposed_clock) { +static int +sdhci_cam_get_possible_host_clock(struct sdhci_slot *slot, int proposed_clock) +{ int max_clock, clock, i; if (proposed_clock == 0) diff --git a/freebsd/sys/dev/usb/controller/usb_controller.c b/freebsd/sys/dev/usb/controller/usb_controller.c index a2633d0d..81901063 100644 --- a/freebsd/sys/dev/usb/controller/usb_controller.c +++ b/freebsd/sys/dev/usb/controller/usb_controller.c @@ -135,7 +135,6 @@ DRIVER_MODULE(usbus, ehci, usb_driver, usb_devclass, 0, 0); DRIVER_MODULE(usbus, xhci, usb_driver, usb_devclass, 0, 0); /* Device Only Drivers */ -DRIVER_MODULE(usbus, at91_udp, usb_driver, usb_devclass, 0, 0); DRIVER_MODULE(usbus, musbotg, usb_driver, usb_devclass, 0, 0); DRIVER_MODULE(usbus, uss820dci, usb_driver, usb_devclass, 0, 0); DRIVER_MODULE(usbus, octusb, usb_driver, usb_devclass, 0, 0); diff --git a/freebsd/sys/dev/usb/input/uep.c b/freebsd/sys/dev/usb/input/uep.c index 701c8550..247bfb9c 100644 --- a/freebsd/sys/dev/usb/input/uep.c +++ b/freebsd/sys/dev/usb/input/uep.c @@ -34,6 +34,8 @@ * http://www.eeti.com.tw/pdf/Software%20Programming%20Guide_v2.0.pdf */ +#include <rtems/bsd/local/opt_evdev.h> + #include <sys/param.h> #include <sys/bus.h> #include <sys/callout.h> @@ -51,9 +53,14 @@ #include <dev/usb/usbhid.h> #include <rtems/bsd/local/usbdevs.h> +#ifdef EVDEV_SUPPORT +#include <dev/evdev/input.h> +#include <dev/evdev/evdev.h> +#else #include <sys/ioccom.h> #include <sys/fcntl.h> #include <sys/tty.h> +#endif #define USB_DEBUG_VAR uep_debug #include <dev/usb/usb_debug.h> @@ -92,11 +99,15 @@ struct uep_softc { struct mtx mtx; struct usb_xfer *xfer[UEP_N_TRANSFER]; +#ifdef EVDEV_SUPPORT + struct evdev_dev *evdev; +#else struct usb_fifo_sc fifo; u_int pollrate; u_int state; #define UEP_ENABLED 0x01 +#endif /* Reassembling buffer. */ u_char buf[UEP_PACKET_LEN_MAX]; @@ -109,6 +120,18 @@ static device_probe_t uep_probe; static device_attach_t uep_attach; static device_detach_t uep_detach; +#ifdef EVDEV_SUPPORT + +static evdev_open_t uep_ev_open; +static evdev_close_t uep_ev_close; + +static const struct evdev_methods uep_evdev_methods = { + .ev_open = &uep_ev_open, + .ev_close = &uep_ev_close, +}; + +#else /* !EVDEV_SUPPORT */ + static usb_fifo_cmd_t uep_start_read; static usb_fifo_cmd_t uep_stop_read; static usb_fifo_open_t uep_open; @@ -123,6 +146,7 @@ static struct usb_fifo_methods uep_fifo_methods = { .f_stop_read = &uep_stop_read, .basename[0] = "uep", }; +#endif /* !EVDEV_SUPPORT */ static int get_pkt_len(u_char *buf) @@ -156,6 +180,9 @@ static void uep_process_pkt(struct uep_softc *sc, u_char *buf) { int32_t x, y; +#ifdef EVDEV_SUPPORT + int touch; +#endif if ((buf[0] & 0xFE) != 0x80) { DPRINTF("bad input packet format 0x%.2x\n", buf[0]); @@ -188,7 +215,17 @@ uep_process_pkt(struct uep_softc *sc, u_char *buf) DPRINTFN(2, "x %u y %u\n", x, y); +#ifdef EVDEV_SUPPORT + touch = buf[0] & (1 << 0); + if (touch) { + evdev_push_abs(sc->evdev, ABS_X, x); + evdev_push_abs(sc->evdev, ABS_Y, y); + } + evdev_push_key(sc->evdev, BTN_TOUCH, touch); + evdev_sync(sc->evdev); +#else uep_put_queue(sc, buf); +#endif } static void @@ -263,12 +300,13 @@ uep_intr_callback(struct usb_xfer *xfer, usb_error_t error) } case USB_ST_SETUP: tr_setup: +#ifndef EVDEV_SUPPORT /* check if we can put more data into the FIFO */ - if (usb_fifo_put_bytes_max(sc->fifo.fp[USB_FIFO_RX]) != 0) { - usbd_xfer_set_frame_len(xfer, 0, - usbd_xfer_max_len(xfer)); - usbd_transfer_submit(xfer); - } + if (usb_fifo_put_bytes_max(sc->fifo.fp[USB_FIFO_RX]) == 0) + break; +#endif + usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer)); + usbd_transfer_submit(xfer); break; default: @@ -332,6 +370,28 @@ uep_attach(device_t dev) goto detach; } +#ifdef EVDEV_SUPPORT + sc->evdev = evdev_alloc(); + evdev_set_name(sc->evdev, device_get_desc(dev)); + evdev_set_phys(sc->evdev, device_get_nameunit(dev)); + evdev_set_id(sc->evdev, BUS_USB, uaa->info.idVendor, + uaa->info.idProduct, 0); + evdev_set_serial(sc->evdev, usb_get_serial(uaa->device)); + evdev_set_methods(sc->evdev, sc, &uep_evdev_methods); + evdev_support_prop(sc->evdev, INPUT_PROP_DIRECT); + evdev_support_event(sc->evdev, EV_SYN); + evdev_support_event(sc->evdev, EV_ABS); + evdev_support_event(sc->evdev, EV_KEY); + evdev_support_key(sc->evdev, BTN_TOUCH); + evdev_support_abs(sc->evdev, ABS_X, 0, 0, UEP_MAX_X, 0, 0, 0); + evdev_support_abs(sc->evdev, ABS_Y, 0, 0, UEP_MAX_Y, 0, 0, 0); + + error = evdev_register_mtx(sc->evdev, &sc->mtx); + if (error) { + DPRINTF("evdev_register_mtx error=%s\n", usbd_errstr(error)); + goto detach; + } +#else /* !EVDEV_SUPPORT */ error = usb_fifo_attach(uaa->device, sc, &sc->mtx, &uep_fifo_methods, &sc->fifo, device_get_unit(dev), -1, uaa->info.bIfaceIndex, UID_ROOT, GID_OPERATOR, 0644); @@ -340,6 +400,7 @@ uep_attach(device_t dev) DPRINTF("usb_fifo_attach error=%s\n", usbd_errstr(error)); goto detach; } +#endif /* !EVDEV_SUPPORT */ sc->buf_len = 0; @@ -356,7 +417,11 @@ uep_detach(device_t dev) { struct uep_softc *sc = device_get_softc(dev); +#ifdef EVDEV_SUPPORT + evdev_free(sc->evdev); +#else usb_fifo_detach(&sc->fifo); +#endif usbd_transfer_unsetup(sc->xfer, UEP_N_TRANSFER); @@ -365,6 +430,32 @@ uep_detach(device_t dev) return (0); } +#ifdef EVDEV_SUPPORT + +static int +uep_ev_close(struct evdev_dev *evdev) +{ + struct uep_softc *sc = evdev_get_softc(evdev); + + mtx_assert(&sc->mtx, MA_OWNED); + usbd_transfer_stop(sc->xfer[UEP_INTR_DT]); + + return (0); +} + +static int +uep_ev_open(struct evdev_dev *evdev) +{ + struct uep_softc *sc = evdev_get_softc(evdev); + + mtx_assert(&sc->mtx, MA_OWNED); + usbd_transfer_start(sc->xfer[UEP_INTR_DT]); + + return (0); +} + +#else /* !EVDEV_SUPPORT */ + static void uep_start_read(struct usb_fifo *fifo) { @@ -426,6 +517,7 @@ uep_close(struct usb_fifo *fifo, int fflags) usb_fifo_free_buffer(fifo); } } +#endif /* !EVDEV_SUPPORT */ static devclass_t uep_devclass; @@ -444,5 +536,8 @@ static driver_t uep_driver = { DRIVER_MODULE(uep, uhub, uep_driver, uep_devclass, NULL, NULL); MODULE_DEPEND(uep, usb, 1, 1, 1); +#ifdef EVDEV_SUPPORT +MODULE_DEPEND(uep, evdev, 1, 1, 1); +#endif MODULE_VERSION(uep, 1); USB_PNP_HOST_INFO(uep_devs); diff --git a/freebsd/sys/dev/usb/input/ukbd.c b/freebsd/sys/dev/usb/input/ukbd.c index 76fe76b6..8fb450bc 100644 --- a/freebsd/sys/dev/usb/input/ukbd.c +++ b/freebsd/sys/dev/usb/input/ukbd.c @@ -367,8 +367,10 @@ static device_detach_t ukbd_detach; static device_resume_t ukbd_resume; #ifdef EVDEV_SUPPORT +static evdev_event_t ukbd_ev_event; + static const struct evdev_methods ukbd_evdev_methods = { - .ev_event = evdev_ev_kbd_event, + .ev_event = ukbd_ev_event, }; #endif @@ -1474,6 +1476,22 @@ ukbd_resume(device_t dev) return (0); } +#ifdef EVDEV_SUPPORT +static void +ukbd_ev_event(struct evdev_dev *evdev, uint16_t type, uint16_t code, + int32_t value) +{ + keyboard_t *kbd = evdev_get_softc(evdev); + + if (evdev_rcpt_mask & EVDEV_RCPT_HW_KBD && + (type == EV_LED || type == EV_REP)) { + mtx_lock(&Giant); + kbd_ev_event(kbd, type, code, value); + mtx_unlock(&Giant); + } +} +#endif + /* early keyboard probe, not supported */ static int ukbd_configure(int flags) diff --git a/freebsd/sys/dev/usb/input/ums.c b/freebsd/sys/dev/usb/input/ums.c index 79bc2291..4a0d1f34 100644 --- a/freebsd/sys/dev/usb/input/ums.c +++ b/freebsd/sys/dev/usb/input/ums.c @@ -952,9 +952,9 @@ ums_reset_buf(struct ums_softc *sc) #ifdef EVDEV_SUPPORT static int -ums_ev_open(struct evdev_dev *evdev, void *ev_softc) +ums_ev_open(struct evdev_dev *evdev) { - struct ums_softc *sc = (struct ums_softc *)ev_softc; + struct ums_softc *sc = evdev_get_softc(evdev); mtx_assert(&sc->sc_mtx, MA_OWNED); @@ -968,10 +968,10 @@ ums_ev_open(struct evdev_dev *evdev, void *ev_softc) return (0); } -static void -ums_ev_close(struct evdev_dev *evdev, void *ev_softc) +static int +ums_ev_close(struct evdev_dev *evdev) { - struct ums_softc *sc = (struct ums_softc *)ev_softc; + struct ums_softc *sc = evdev_get_softc(evdev); mtx_assert(&sc->sc_mtx, MA_OWNED); @@ -979,6 +979,8 @@ ums_ev_close(struct evdev_dev *evdev, void *ev_softc) if (sc->sc_fflags == 0) ums_stop_rx(sc); + + return (0); } #endif diff --git a/freebsd/sys/dev/usb/net/if_ure.c b/freebsd/sys/dev/usb/net/if_ure.c index 8a88feae..bcae02cb 100644 --- a/freebsd/sys/dev/usb/net/if_ure.c +++ b/freebsd/sys/dev/usb/net/if_ure.c @@ -70,6 +70,7 @@ SYSCTL_INT(_hw_usb_ure, OID_AUTO, debug, CTLFLAG_RWTUN, &ure_debug, 0, static const STRUCT_USB_HOST_ID ure_devs[] = { #define URE_DEV(v,p,i) { USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, i) } URE_DEV(LENOVO, RTL8153, 0), + URE_DEV(NVIDIA, RTL8153, 0), URE_DEV(REALTEK, RTL8152, URE_FLAG_8152), URE_DEV(REALTEK, RTL8153, 0), URE_DEV(TPLINK, RTL8153, 0), diff --git a/freebsd/sys/dev/usb/serial/u3g.c b/freebsd/sys/dev/usb/serial/u3g.c index 6f1cfdb1..8d72ef49 100644 --- a/freebsd/sys/dev/usb/serial/u3g.c +++ b/freebsd/sys/dev/usb/serial/u3g.c @@ -210,6 +210,7 @@ static const STRUCT_USB_HOST_ID u3g_devs[] = { U3G_DEV(ALINK, 3G, 0), U3G_DEV(ALINK, 3GU, 0), U3G_DEV(ALINK, DWM652U5, 0), + U3G_DEV(ALINK, SIM7600E, 0), U3G_DEV(AMOI, H01, 0), U3G_DEV(AMOI, H01A, 0), U3G_DEV(AMOI, H02, 0), diff --git a/freebsd/sys/dev/usb/usb_hid.c b/freebsd/sys/dev/usb/usb_hid.c index c2d93f3a..7ae052b7 100644 --- a/freebsd/sys/dev/usb/usb_hid.c +++ b/freebsd/sys/dev/usb/usb_hid.c @@ -76,6 +76,7 @@ static uint8_t hid_get_byte(struct hid_data *s, const uint16_t wSize); #define MAXUSAGE 64 #define MAXPUSH 4 #define MAXID 16 +#define MAXLOCCNT 1024 struct hid_pos_data { int32_t rid; @@ -93,10 +94,10 @@ struct hid_data { int32_t usage_last; /* last seen usage */ uint32_t loc_size; /* last seen size */ uint32_t loc_count; /* last seen count */ + uint32_t ncount; /* end usage item count */ + uint32_t icount; /* current usage item count */ uint8_t kindset; /* we have 5 kinds so 8 bits are enough */ uint8_t pushlevel; /* current pushlevel */ - uint8_t ncount; /* end usage item count */ - uint8_t icount; /* current usage item count */ uint8_t nusage; /* end "usages_min/max" index */ uint8_t iusage; /* current "usages_min/max" index */ uint8_t ousage; /* current "usages_min/max" offset */ @@ -349,18 +350,19 @@ hid_get_item(struct hid_data *s, struct hid_item *h) switch (bTag) { case 8: /* Input */ c->kind = hid_input; - c->flags = dval; ret: + c->flags = dval; c->loc.count = s->loc_count; c->loc.size = s->loc_size; if (c->flags & HIO_VARIABLE) { /* range check usage count */ - if (c->loc.count > 255) { + if (c->loc.count > MAXLOCCNT) { DPRINTFN(0, "Number of " - "items(%u) truncated to 255\n", - (unsigned)(c->loc.count)); - s->ncount = 255; + "items(%u) truncated to %u\n", + (unsigned)(c->loc.count), + MAXLOCCNT); + s->ncount = MAXLOCCNT; } else s->ncount = c->loc.count; @@ -376,7 +378,6 @@ hid_get_item(struct hid_data *s, struct hid_item *h) case 9: /* Output */ c->kind = hid_output; - c->flags = dval; goto ret; case 10: /* Collection */ c->kind = hid_collection; @@ -387,7 +388,6 @@ hid_get_item(struct hid_data *s, struct hid_item *h) return (1); case 11: /* Feature */ c->kind = hid_feature; - c->flags = dval; goto ret; case 12: /* End collection */ c->kind = hid_endcollection; diff --git a/freebsd/sys/dev/usb/usb_request.c b/freebsd/sys/dev/usb/usb_request.c index cb69ce0e..d2a15f3c 100644 --- a/freebsd/sys/dev/usb/usb_request.c +++ b/freebsd/sys/dev/usb/usb_request.c @@ -992,7 +992,7 @@ usbd_req_get_desc(struct usb_device *udev, uint8_t retries) { struct usb_device_request req; - uint8_t *buf; + uint8_t *buf = desc; usb_error_t err; DPRINTFN(4, "id=%d, type=%d, index=%d, max_len=%d\n", @@ -1014,6 +1014,32 @@ usbd_req_get_desc(struct usb_device *udev, err = usbd_do_request_flags(udev, mtx, &req, desc, 0, NULL, 500 /* ms */); + if (err != 0 && err != USB_ERR_TIMEOUT && + min_len != max_len) { + /* clear descriptor data */ + memset(desc, 0, max_len); + + /* try to read full descriptor length */ + USETW(req.wLength, max_len); + + err = usbd_do_request_flags(udev, mtx, &req, + desc, USB_SHORT_XFER_OK, NULL, 500 /* ms */); + + if (err == 0) { + /* verify length */ + if (buf[0] > max_len) + buf[0] = max_len; + else if (buf[0] < 2) + err = USB_ERR_INVAL; + + min_len = buf[0]; + + /* enforce descriptor type */ + buf[1] = type; + goto done; + } + } + if (err) { if (!retries) { goto done; @@ -1024,7 +1050,6 @@ usbd_req_get_desc(struct usb_device *udev, continue; } - buf = desc; if (min_len == max_len) { diff --git a/freebsd/sys/dev/usb/wlan/if_run.c b/freebsd/sys/dev/usb/wlan/if_run.c index 41f97ba4..3bd247e3 100644 --- a/freebsd/sys/dev/usb/wlan/if_run.c +++ b/freebsd/sys/dev/usb/wlan/if_run.c @@ -210,6 +210,7 @@ static const STRUCT_USB_HOST_ID run_devs[] = { RUN_DEV(CYBERTAN, RT2870), RUN_DEV(DLINK, RT2870), RUN_DEV(DLINK, RT3072), + RUN_DEV(DLINK, DWA125A3), RUN_DEV(DLINK, DWA127), RUN_DEV(DLINK, DWA140B3), RUN_DEV(DLINK, DWA160B2), @@ -303,6 +304,7 @@ static const STRUCT_USB_HOST_ID run_devs[] = { RUN_DEV(RALINK, RT3572), RUN_DEV(RALINK, RT3573), RUN_DEV(RALINK, RT5370), + RUN_DEV(RALINK, RT5372), RUN_DEV(RALINK, RT5572), RUN_DEV(RALINK, RT8070), RUN_DEV(SAMSUNG, WIS09ABGN), |