From owner-svn-soc-all@freebsd.org Mon Jul 25 07:40:13 2016 Return-Path: Delivered-To: svn-soc-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id B2F01BA31A5 for ; Mon, 25 Jul 2016 07:40:13 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id A5C8B1A3B for ; Mon, 25 Jul 2016 07:40:13 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.15.2/8.15.2) with ESMTP id u6P7eDOL062177 for ; Mon, 25 Jul 2016 07:40:13 GMT (envelope-from vincenzo@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.15.2/8.15.2/Submit) id u6P7e939062109 for svn-soc-all@FreeBSD.org; Mon, 25 Jul 2016 07:40:09 GMT (envelope-from vincenzo@FreeBSD.org) Date: Mon, 25 Jul 2016 07:40:09 GMT Message-Id: <201607250740.u6P7e939062109@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to vincenzo@FreeBSD.org using -f From: vincenzo@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r306721 - soc2016/vincenzo/head/sys/dev/netmap MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 25 Jul 2016 07:40:13 -0000 Author: vincenzo Date: Mon Jul 25 07:40:08 2016 New Revision: 306721 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=306721 Log: freebsd: ptnet: code cleanup and woraround removal Various changes: - add support for ptnetmap stats - share netmap adapter callbacks with the linux driver in order to reuse code - fix netmap drivers initialization long-standing workaround, introducing proper priorities - reorganize ptnetmap guest adapter to put more functionality in the common code (used by all the guest OS drivers) Modified: soc2016/vincenzo/head/sys/dev/netmap/if_ptnet.c soc2016/vincenzo/head/sys/dev/netmap/netmap.c soc2016/vincenzo/head/sys/dev/netmap/netmap_freebsd.c soc2016/vincenzo/head/sys/dev/netmap/netmap_kern.h soc2016/vincenzo/head/sys/dev/netmap/netmap_mem2.c soc2016/vincenzo/head/sys/dev/netmap/netmap_vale.c soc2016/vincenzo/head/sys/dev/netmap/netmap_virt.h soc2016/vincenzo/head/sys/dev/netmap/ptnetmap.c Modified: soc2016/vincenzo/head/sys/dev/netmap/if_ptnet.c ============================================================================== --- soc2016/vincenzo/head/sys/dev/netmap/if_ptnet.c Mon Jul 25 05:33:19 2016 (r306720) +++ soc2016/vincenzo/head/sys/dev/netmap/if_ptnet.c Mon Jul 25 07:40:08 2016 (r306721) @@ -42,6 +42,7 @@ #include #include #include +#include #include #include @@ -92,6 +93,7 @@ #error "INET not defined, cannot support offloadings" #endif +//#define PTNETMAP_STATS //#define DEBUG #ifdef DEBUG #define DBG(x) x @@ -109,6 +111,10 @@ uint64_t errors; /* if_[io]errors */ uint64_t iqdrops; /* if_iqdrops */ uint64_t mcasts; /* if_[io]mcasts */ +#ifdef PTNETMAP_STATS + uint64_t intrs; + uint64_t kicks; +#endif /* PTNETMAP_STATS */ }; struct ptnet_queue { @@ -121,6 +127,9 @@ struct mtx lock; struct buf_ring *bufring; /* for TX queues */ struct ptnet_queue_stats stats; +#ifdef PTNETMAP_STATS + struct ptnet_queue_stats last_stats; +#endif /* PTNETMAP_STATS */ struct taskqueue *taskq; struct task task; char lock_name[16]; @@ -142,10 +151,6 @@ uint32_t ptfeatures; unsigned int vnet_hdr_len; - /* Reference counter used to track the regif operations on the - * passed-through netmap port. */ - int backend_regifs; - /* PCI BARs support. */ struct resource *iomem; struct resource *msix_mem; @@ -158,12 +163,12 @@ unsigned int min_tx_space; - struct netmap_pt_guest_adapter *ptna_nm; - struct netmap_pt_guest_adapter ptna_dr; - /* XXX we should move ptna_dr and backend_regifs inside struct - * netmap_pt_guest_adapter and have just one instance of that. */ + struct netmap_pt_guest_adapter *ptna; struct callout tick; +#ifdef PTNETMAP_STATS + struct timeval last_ts; +#endif /* PTNETMAP_STATS */ }; #define PTNET_CORE_LOCK(_sc) mtx_lock(&(_sc)->lock) @@ -197,9 +202,6 @@ static uint32_t ptnet_nm_ptctl(struct ifnet *ifp, uint32_t cmd); static int ptnet_nm_config(struct netmap_adapter *na, unsigned *txr, unsigned *txd, unsigned *rxr, unsigned *rxd); -static int ptnet_nm_krings_create(struct netmap_adapter *na); -static void ptnet_nm_krings_delete(struct netmap_adapter *na); -static void ptnet_nm_dtor(struct netmap_adapter *na); static void ptnet_update_vnet_hdr(struct ptnet_softc *sc); static int ptnet_nm_register(struct netmap_adapter *na, int onoff); static int ptnet_nm_txsync(struct netmap_kring *kring, int flags); @@ -234,9 +236,10 @@ sizeof(struct ptnet_softc) }; +/* We use (SI_ORDER_MIDDLE+2) here, see DEV_MODULE_ORDERED() invocation. */ static devclass_t ptnet_devclass; DRIVER_MODULE_ORDERED(ptnet, pci, ptnet_driver, ptnet_devclass, - NULL, NULL, SI_ORDER_MIDDLE + 1); + NULL, NULL, SI_ORDER_MIDDLE + 2); static int ptnet_probe(device_t dev) @@ -251,7 +254,13 @@ return (BUS_PROBE_DEFAULT); } -extern int netmap_initialized; +static inline void ptnet_kick(struct ptnet_queue *pq) +{ +#ifdef PTNETMAP_STATS + pq->stats.kicks ++; +#endif /* PTNETMAP_STATS */ + bus_write_4(pq->sc->iomem, pq->kick, 0); +} #define PTNET_BUF_RING_SIZE 4096 #define PTNET_RX_BUDGET 512 @@ -280,11 +289,6 @@ int err, rid; int i; - if (!netmap_initialized) { - device_printf(dev, "Netmap still not initialized\n"); - return (ENXIO); - } - sc = device_get_softc(dev); sc->dev = dev; @@ -435,8 +439,6 @@ mtx_init(&sc->lock, sc->lock_name, "ptnet core lock", MTX_DEF); callout_init_mtx(&sc->tick, &sc->lock, 0); - sc->backend_regifs = 0; - /* Prepare a netmap_adapter struct instance to do netmap_attach(). */ nifp_offset = bus_read_4(sc->iomem, PTNET_IO_NIFP_OFS); memset(&na_arg, 0, sizeof(na_arg)); @@ -458,24 +460,13 @@ /* Now a netmap adapter for this ifp has been allocated, and it * can be accessed through NA(ifp). We also have to initialize the CSB * pointer. */ - sc->ptna_nm = (struct netmap_pt_guest_adapter *)NA(ifp); - sc->ptna_nm->csb = sc->csb; + sc->ptna = (struct netmap_pt_guest_adapter *)NA(ifp); /* If virtio-net header was negotiated, set the virt_hdr_len field in * the netmap adapter, to inform users that this netmap adapter requires * the application to deal with the headers. */ ptnet_update_vnet_hdr(sc); - /* Initialize a separate pass-through netmap adapter that is going to - * be used by this driver only, and so never exposed to netmap. We - * only need a subset of the available fields. */ - memset(&sc->ptna_dr, 0, sizeof(sc->ptna_dr)); - sc->ptna_dr.hwup.up.ifp = ifp; - sc->ptna_dr.hwup.up.nm_mem = sc->ptna_nm->hwup.up.nm_mem; - netmap_mem_get(sc->ptna_dr.hwup.up.nm_mem); - sc->ptna_dr.hwup.up.nm_config = ptnet_nm_config; - sc->ptna_dr.csb = sc->csb; - device_printf(dev, "%s() completed\n", __func__); return (0); @@ -513,8 +504,6 @@ ether_ifdetach(sc->ifp); /* Uninitialize netmap adapters for this device. */ - netmap_mem_put(sc->ptna_dr.hwup.up.nm_mem); - memset(&sc->ptna_dr, 0, sizeof(sc->ptna_dr)); netmap_detach(sc->ifp); ifmedia_removeall(&sc->media); @@ -827,7 +816,8 @@ ptnet_init_locked(struct ptnet_softc *sc) { struct ifnet *ifp = sc->ifp; - struct netmap_adapter *na_dr = &sc->ptna_dr.hwup.up; + struct netmap_adapter *na_dr = &sc->ptna->dr.up; + struct netmap_adapter *na_nm = &sc->ptna->hwup.up; unsigned int nm_buf_size; int ret; @@ -859,8 +849,8 @@ return ret; } - if (sc->backend_regifs == 0) { - ret = ptnet_nm_krings_create(na_dr); + if (sc->ptna->backend_regifs == 0) { + ret = ptnet_nm_krings_create(na_nm); if (ret) { device_printf(sc->dev, "ptnet_nm_krings_create() " "failed\n"); @@ -905,7 +895,7 @@ err_get_lut: netmap_mem_rings_delete(na_dr); err_rings_create: - ptnet_nm_krings_delete(na_dr); + ptnet_nm_krings_delete(na_nm); err_mem_finalize: netmap_mem_deref(na_dr->nm_mem, na_dr); @@ -917,7 +907,8 @@ ptnet_stop(struct ptnet_softc *sc) { struct ifnet *ifp = sc->ifp; - struct netmap_adapter *na_dr = &sc->ptna_dr.hwup.up; + struct netmap_adapter *na_dr = &sc->ptna->dr.up; + struct netmap_adapter *na_nm = &sc->ptna->hwup.up; int i; device_printf(sc->dev, "%s\n", __func__); @@ -938,9 +929,9 @@ ptnet_nm_register(na_dr, 0 /* off */); - if (sc->backend_regifs == 0) { + if (sc->ptna->backend_regifs == 0) { netmap_mem_rings_delete(na_dr); - ptnet_nm_krings_delete(na_dr); + ptnet_nm_krings_delete(na_nm); } netmap_mem_deref(na_dr->nm_mem, na_dr); @@ -1016,6 +1007,31 @@ ifp->if_ierrors = stats[1].errors; ifp->if_iqdrops = stats[1].iqdrops; +#ifdef PTNETMAP_STATS + for (i = 0; i < sc->num_rings; i++) { + struct ptnet_queue *pq = sc->queues + i; + struct ptnet_queue_stats cur = pq->stats; + struct timeval now; + unsigned int delta; + + microtime(&now); + delta = now.tv_usec - sc->last_ts.tv_usec + + (now.tv_sec - sc->last_ts.tv_sec) * 1000000; + delta /= 1000; /* in milliseconds */ + + if (delta == 0) + continue; + + device_printf(sc->dev, "#%d[%u ms]:pkts %lu, kicks %lu, " + "intr %lu\n", i, delta, + (cur.packets - pq->last_stats.packets), + (cur.kicks - pq->last_stats.kicks), + (cur.intrs - pq->last_stats.intrs)); + pq->last_stats = cur; + } + microtime(&sc->last_ts); +#endif /* PTNETMAP_STATS */ + callout_schedule(&sc->tick, hz); } @@ -1058,58 +1074,6 @@ return 0; } -/* XXX krings create/delete and register functions should be shared - * with the Linux driver. */ -static int -ptnet_nm_krings_create(struct netmap_adapter *na) -{ - /* Here (na == &sc->ptna_nm->hwup.up || na == &sc->ptna_dr.hwup.up). */ - struct ptnet_softc *sc = na->ifp->if_softc; - struct netmap_adapter *na_nm = &sc->ptna_nm->hwup.up; - struct netmap_adapter *na_dr = &sc->ptna_dr.hwup.up; - int ret; - - if (sc->backend_regifs) { - return 0; - } - - /* Create krings on the public netmap adapter. */ - ret = netmap_hw_krings_create(na_nm); - if (ret) { - return ret; - } - - /* Copy krings into the netmap adapter private to the driver. */ - na_dr->tx_rings = na_nm->tx_rings; - na_dr->rx_rings = na_nm->rx_rings; - - return 0; -} - -static void -ptnet_nm_krings_delete(struct netmap_adapter *na) -{ - /* Here (na == &sc->ptna_nm->hwup.up || na == &sc->ptna_dr.hwup.up). */ - struct ptnet_softc *sc = na->ifp->if_softc; - struct netmap_adapter *na_nm = &sc->ptna_nm->hwup.up; - struct netmap_adapter *na_dr = &sc->ptna_dr.hwup.up; - - if (sc->backend_regifs) { - return; - } - - na_dr->tx_rings = NULL; - na_dr->rx_rings = NULL; - - netmap_hw_krings_delete(na_nm); -} - -static void -ptnet_nm_dtor(struct netmap_adapter *na) -{ - netmap_mem_pt_guest_ifp_del(na->nm_mem, na->ifp); -} - static void ptnet_sync_from_csb(struct ptnet_softc *sc, struct netmap_adapter *na) { @@ -1146,7 +1110,7 @@ ptnet_update_vnet_hdr(struct ptnet_softc *sc) { sc->vnet_hdr_len = ptnet_vnet_hdr ? PTNET_HDR_SIZE : 0; - sc->ptna_nm->hwup.up.virt_hdr_len = sc->vnet_hdr_len; + sc->ptna->hwup.up.virt_hdr_len = sc->vnet_hdr_len; bus_write_4(sc->iomem, PTNET_IO_VNET_HDR_LEN, sc->vnet_hdr_len); } @@ -1156,14 +1120,14 @@ /* device-specific */ struct ifnet *ifp = na->ifp; struct ptnet_softc *sc = ifp->if_softc; - int native = (na == &sc->ptna_nm->hwup.up); + int native = (na == &sc->ptna->hwup.up); struct ptnet_queue *pq; enum txrx t; int ret = 0; int i; if (!onoff) { - sc->backend_regifs--; + sc->ptna->backend_regifs--; } /* If this is the last netmap client, guest interrupt enable flags may @@ -1181,7 +1145,7 @@ } if (onoff) { - if (sc->backend_regifs == 0) { + if (sc->ptna->backend_regifs == 0) { /* Initialize notification enable fields in the CSB. */ for (i = 0; i < sc->num_rings; i++) { pq = sc->queues + i; @@ -1205,7 +1169,7 @@ /* Sync from CSB must be done after REGIF PTCTL. Skip this * step only if this is a netmap client and it is not the * first one. */ - if ((!native && sc->backend_regifs == 0) || + if ((!native && sc->ptna->backend_regifs == 0) || (native && na->active_fds == 0)) { ptnet_sync_from_csb(sc, na); } @@ -1214,7 +1178,7 @@ * to replace if_transmit method, nor set NAF_NETMAP_ON */ if (native) { for_rx_tx(t) { - for (i=0; ibackend_regifs == 0) { + if (sc->ptna->backend_regifs == 0) { ret = ptnet_nm_ptctl(ifp, NET_PARAVIRT_PTCTL_UNREGIF); } } if (onoff) { - sc->backend_regifs++; + sc->ptna->backend_regifs++; } return ret; @@ -1266,7 +1230,7 @@ notify = netmap_pt_guest_txsync(pq->ptring, kring, flags); if (notify) { - bus_write_4(sc->iomem, pq->kick, 0); + ptnet_kick(pq); } return 0; @@ -1281,7 +1245,7 @@ notify = netmap_pt_guest_rxsync(pq->ptring, kring, flags); if (notify) { - bus_write_4(sc->iomem, pq->kick, 0); + ptnet_kick(pq); } return 0; @@ -1294,6 +1258,9 @@ struct ptnet_softc *sc = pq->sc; DBG(device_printf(sc->dev, "Tx interrupt #%d\n", pq->kring_id)); +#ifdef PTNETMAP_STATS + pq->stats.intrs ++; +#endif /* PTNETMAP_STATS */ if (netmap_tx_irq(sc->ifp, pq->kring_id) != NM_IRQ_PASS) { return; @@ -1314,6 +1281,9 @@ unsigned int unused; DBG(device_printf(sc->dev, "Rx interrupt #%d\n", pq->kring_id)); +#ifdef PTNETMAP_STATS + pq->stats.intrs ++; +#endif /* PTNETMAP_STATS */ if (netmap_rx_irq(sc->ifp, pq->kring_id, &unused) != NM_IRQ_PASS) { return; @@ -1675,7 +1645,7 @@ /* Kick the host if needed. */ if (NM_ACCESS_ONCE(ptring->host_need_kick)) { ptring->sync_flags = sync_flags; - bus_write_4(pq->sc->iomem, pq->kick, 0); + ptnet_kick(pq); } } @@ -1691,7 +1661,7 @@ { struct ptnet_softc *sc = pq->sc; bool have_vnet_hdr = sc->vnet_hdr_len; - struct netmap_adapter *na = &sc->ptna_dr.hwup.up; + struct netmap_adapter *na = &sc->ptna->dr.up; struct ifnet *ifp = sc->ifp; unsigned int batch_count = 0; struct ptnet_ring *ptring; @@ -1985,7 +1955,7 @@ struct ptnet_softc *sc = pq->sc; bool have_vnet_hdr = sc->vnet_hdr_len; struct ptnet_ring *ptring = pq->ptring; - struct netmap_adapter *na = &sc->ptna_dr.hwup.up; + struct netmap_adapter *na = &sc->ptna->dr.up; struct netmap_kring *kring = na->rx_rings + pq->kring_id; struct netmap_ring *ring = kring->ring; unsigned int const lim = kring->nkr_num_slots - 1; Modified: soc2016/vincenzo/head/sys/dev/netmap/netmap.c ============================================================================== --- soc2016/vincenzo/head/sys/dev/netmap/netmap.c Mon Jul 25 05:33:19 2016 (r306720) +++ soc2016/vincenzo/head/sys/dev/netmap/netmap.c Mon Jul 25 07:40:08 2016 (r306721) @@ -2865,6 +2865,17 @@ ptna = (struct netmap_pt_guest_adapter *) NA(ifp); ptna->csb = csb; + /* Initialize a separate pass-through netmap adapter that is going to + * be used by the ptnet driver only, and so never exposed to netmap + * applications. We only need a subset of the available fields. */ + memset(&ptna->dr, 0, sizeof(ptna->dr)); + ptna->dr.up.ifp = ifp; + ptna->dr.up.nm_mem = ptna->hwup.up.nm_mem; + netmap_mem_get(ptna->dr.up.nm_mem); + ptna->dr.up.nm_config = ptna->hwup.up.nm_config; + + ptna->backend_regifs = 0; + return 0; } #endif /* WITH_PTNETMAP_GUEST */ Modified: soc2016/vincenzo/head/sys/dev/netmap/netmap_freebsd.c ============================================================================== --- soc2016/vincenzo/head/sys/dev/netmap/netmap_freebsd.c Mon Jul 25 05:33:19 2016 (r306720) +++ soc2016/vincenzo/head/sys/dev/netmap/netmap_freebsd.c Mon Jul 25 07:40:08 2016 (r306721) @@ -33,7 +33,7 @@ #include /* defines used in kernel.h */ #include /* POLLIN, POLLOUT */ #include /* types used in module initialization */ -#include /* DEV_MODULE */ +#include /* DEV_MODULE_ORDERED */ #include #include /* kern_ioctl() */ @@ -595,9 +595,11 @@ sizeof(struct ptnetmap_memdev), }; +/* We use (SI_ORDER_MIDDLE+1) here, see DEV_MODULE_ORDERED() invocation + * below. */ static devclass_t ptnetmap_devclass; DRIVER_MODULE_ORDERED(ptn_memdev, pci, ptn_memdev_driver, ptnetmap_devclass, - NULL, NULL, SI_ORDER_MIDDLE); + NULL, NULL, SI_ORDER_MIDDLE + 1); /* * I/O port read/write wrappers. @@ -680,8 +682,6 @@ return (BUS_PROBE_DEFAULT); } -int netmap_initialized = 0; /* XXX temporary hack */ - /* Device initialization routine. */ static int ptn_memdev_attach(device_t dev) @@ -692,11 +692,6 @@ D("ptn_memdev_driver attach"); - if (!netmap_initialized) { - device_printf(dev, "Netmap still not initialized\n"); - return (ENXIO); - } - ptn_dev = device_get_softc(dev); ptn_dev->dev = dev; @@ -759,11 +754,6 @@ return bus_generic_shutdown(dev); } -int -nm_os_pt_memdev_init(void) { return 0; } - -void -nm_os_pt_memdev_uninit(void) { } #endif /* WITH_PTNETMAP_GUEST */ /* @@ -1047,11 +1037,11 @@ struct nm_kthread_ctx *ctx = &nmk->worker_ctx; uint64_t old_scheduled = nmk->scheduled; - thread_lock(curthread); if (nmk->affinity >= 0) { + thread_lock(curthread); sched_bind(curthread, nmk->affinity); + thread_unlock(curthread); } - thread_unlock(curthread); while (nmk->run) { /* @@ -1071,7 +1061,7 @@ * mechanism and we continually execute worker_fn() */ if (!ctx->ioevent_file) { - ctx->worker_fn(ctx->worker_private); /* worker_body */ + ctx->worker_fn(ctx->worker_private); /* worker body */ } else { /* checks if there is a pending notification */ mtx_lock(&nmk->worker_lock); @@ -1079,13 +1069,13 @@ old_scheduled = nmk->scheduled; mtx_unlock(&nmk->worker_lock); - ctx->worker_fn(ctx->worker_private); /* worker_body */ + ctx->worker_fn(ctx->worker_private); /* worker body */ continue; } else if (nmk->run) { - /* wait on event with timetout 1 second */ - msleep_spin_sbt(ctx->ioevent_file, &nmk->worker_lock, - "nmk_event", SBT_1S, SBT_1S, C_ABSOLUTE); + /* wait on event with one second timeout */ + msleep_spin(ctx->ioevent_file, &nmk->worker_lock, + "nmk_ev", hz); nmk->scheduled++; } mtx_unlock(&nmk->worker_lock); @@ -1436,8 +1426,6 @@ switch (event) { case MOD_LOAD: error = netmap_init(); - if (!error) - netmap_initialized = 1; break; case MOD_UNLOAD: @@ -1451,7 +1439,6 @@ error = EBUSY; break; } - netmap_initialized = 0; netmap_fini(); break; @@ -1463,8 +1450,18 @@ return (error); } - -DEV_MODULE(netmap, netmap_loader, NULL); +/* + * The netmap module contains three drivers: (i) the netmap character device + * driver; (ii) the ptnetmap memdev PCI device driver, (iii) the ptnet PCI + * device driver. The attach() routines of both (ii) and (iii) need the + * lock of the global allocator, and such lock is initialized in netmap_init(), + * which is part of (i). + * Therefore, we make sure that (i) is loaded before (ii) and (iii), using + * the 'order' parameter of driver declaration macros. For (i), we specify + * SI_ORDER_MIDDLE, while higher orders are used with the DRIVER_MODULE_ORDERED + * macros for (ii) and (iii). + */ +DEV_MODULE_ORDERED(netmap, netmap_loader, NULL, SI_ORDER_MIDDLE); MODULE_DEPEND(netmap, pci, 1, 1, 1); MODULE_VERSION(netmap, 1); /* reduce conditional code */ Modified: soc2016/vincenzo/head/sys/dev/netmap/netmap_kern.h ============================================================================== --- soc2016/vincenzo/head/sys/dev/netmap/netmap_kern.h Mon Jul 25 05:33:19 2016 (r306720) +++ soc2016/vincenzo/head/sys/dev/netmap/netmap_kern.h Mon Jul 25 07:40:08 2016 (r306721) @@ -2049,8 +2049,21 @@ * netmap adapter for guest ptnetmap ports */ struct netmap_pt_guest_adapter { + /* The netmap adapter to be used by netmap applications. + * This field must be the first, to allow upcast. */ struct netmap_hw_adapter hwup; + + /* The netmap adapter to be used by the driver. */ + struct netmap_hw_adapter dr; + void *csb; + + /* Reference counter to track users of backend netmap port: the + * network stack and netmap clients. + * Used to decide when we need (de)allocate krings/rings and + * start (stop) ptnetmap kthreads. */ + int backend_regifs; + }; int netmap_pt_guest_attach(struct netmap_adapter *, void *, @@ -2060,6 +2073,9 @@ int flags); bool netmap_pt_guest_rxsync(struct ptnet_ring *ptring, struct netmap_kring *kring, int flags); +int ptnet_nm_krings_create(struct netmap_adapter *na); +void ptnet_nm_krings_delete(struct netmap_adapter *na); +void ptnet_nm_dtor(struct netmap_adapter *na); #endif /* WITH_PTNETMAP_GUEST */ #endif /* _NET_NETMAP_KERN_H_ */ Modified: soc2016/vincenzo/head/sys/dev/netmap/netmap_mem2.c ============================================================================== --- soc2016/vincenzo/head/sys/dev/netmap/netmap_mem2.c Mon Jul 25 05:33:19 2016 (r306720) +++ soc2016/vincenzo/head/sys/dev/netmap/netmap_mem2.c Mon Jul 25 07:40:08 2016 (r306721) @@ -562,19 +562,9 @@ return ret; } -#if defined(__FreeBSD__) -extern int netmap_initialized; -#endif - static void nm_mem_release_id(struct netmap_mem_d *nmd) { -#if defined(__FreeBSD__) - if (!netmap_initialized) { - D("skip, nm_mem could be gone"); - return; - } -#endif NMA_LOCK(&nm_mem); nmd->prev->next = nmd->next; Modified: soc2016/vincenzo/head/sys/dev/netmap/netmap_vale.c ============================================================================== --- soc2016/vincenzo/head/sys/dev/netmap/netmap_vale.c Mon Jul 25 05:33:19 2016 (r306720) +++ soc2016/vincenzo/head/sys/dev/netmap/netmap_vale.c Mon Jul 25 07:40:08 2016 (r306721) @@ -1514,6 +1514,7 @@ uint32_t sh, dh; u_int dst, mysrc = na->bdg_port; uint64_t smac, dmac; + uint8_t indbuf[12]; /* safety check, unfortunately we have many cases */ if (buf_len >= 14 + na->up.virt_hdr_len) { @@ -1529,6 +1530,14 @@ RD(5, "invalid buf format, length %d", buf_len); return NM_BDG_NOPORT; } + + if (ft->ft_flags & NS_INDIRECT) { + if (copyin(buf, indbuf, sizeof(indbuf))) { + return NM_BDG_NOPORT; + } + buf = indbuf; + } + dmac = le64toh(*(uint64_t *)(buf)) & 0xffffffffffff; smac = le64toh(*(uint64_t *)(buf + 4)); smac >>= 16; Modified: soc2016/vincenzo/head/sys/dev/netmap/netmap_virt.h ============================================================================== --- soc2016/vincenzo/head/sys/dev/netmap/netmap_virt.h Mon Jul 25 05:33:19 2016 (r306720) +++ soc2016/vincenzo/head/sys/dev/netmap/netmap_virt.h Mon Jul 25 07:40:08 2016 (r306721) @@ -475,8 +475,6 @@ /* ptnetmap_memdev routines used to talk with ptnetmap_memdev device driver */ struct ptnetmap_memdev; -int nm_os_pt_memdev_init(void); -void nm_os_pt_memdev_uninit(void); int nm_os_pt_memdev_iomap(struct ptnetmap_memdev *, vm_paddr_t *, void **); void nm_os_pt_memdev_iounmap(struct ptnetmap_memdev *); #endif /* WITH_PTNETMAP_GUEST */ Modified: soc2016/vincenzo/head/sys/dev/netmap/ptnetmap.c ============================================================================== --- soc2016/vincenzo/head/sys/dev/netmap/ptnetmap.c Mon Jul 25 05:33:19 2016 (r306720) +++ soc2016/vincenzo/head/sys/dev/netmap/ptnetmap.c Mon Jul 25 07:40:08 2016 (r306721) @@ -1130,6 +1130,11 @@ DBG(D("%s", pth_na->up.name)); + /* The equivalent of NETMAP_PT_HOST_DELETE if the hypervisor + * didn't do it. */ + ptnetmap_stop_kthreads(pth_na); + ptnetmap_delete(pth_na); + parent->na_flags &= ~NAF_BUSY; netmap_adapter_put(pth_na->parent); @@ -1382,4 +1387,63 @@ return notify; } + +/* + * Callbacks for ptnet drivers: nm_krings_create, nm_krings_delete, nm_dtor. + */ +int +ptnet_nm_krings_create(struct netmap_adapter *na) +{ + struct netmap_pt_guest_adapter *ptna = + (struct netmap_pt_guest_adapter *)na; /* Upcast. */ + struct netmap_adapter *na_nm = &ptna->hwup.up; + struct netmap_adapter *na_dr = &ptna->dr.up; + int ret; + + if (ptna->backend_regifs) { + return 0; + } + + /* Create krings on the public netmap adapter. */ + ret = netmap_hw_krings_create(na_nm); + if (ret) { + return ret; + } + + /* Copy krings into the netmap adapter private to the driver. */ + na_dr->tx_rings = na_nm->tx_rings; + na_dr->rx_rings = na_nm->rx_rings; + + return 0; +} + +void +ptnet_nm_krings_delete(struct netmap_adapter *na) +{ + struct netmap_pt_guest_adapter *ptna = + (struct netmap_pt_guest_adapter *)na; /* Upcast. */ + struct netmap_adapter *na_nm = &ptna->hwup.up; + struct netmap_adapter *na_dr = &ptna->dr.up; + + if (ptna->backend_regifs) { + return; + } + + na_dr->tx_rings = NULL; + na_dr->rx_rings = NULL; + + netmap_hw_krings_delete(na_nm); +} + +void +ptnet_nm_dtor(struct netmap_adapter *na) +{ + struct netmap_pt_guest_adapter *ptna = + (struct netmap_pt_guest_adapter *)na; + + netmap_mem_put(ptna->dr.up.nm_mem); + memset(&ptna->dr, 0, sizeof(ptna->dr)); + netmap_mem_pt_guest_ifp_del(na->nm_mem, na->ifp); +} + #endif /* WITH_PTNETMAP_GUEST */ From owner-svn-soc-all@freebsd.org Sat Jul 30 11:17:37 2016 Return-Path: Delivered-To: svn-soc-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 88CEABA784B for ; Sat, 30 Jul 2016 11:17:37 +0000 (UTC) (envelope-from iateaca@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 7C1C9174C for ; Sat, 30 Jul 2016 11:17:37 +0000 (UTC) (envelope-from iateaca@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.15.2/8.15.2) with ESMTP id u6UBHbQL033102 for ; Sat, 30 Jul 2016 11:17:37 GMT (envelope-from iateaca@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.15.2/8.15.2/Submit) id u6UBHatY033099 for svn-soc-all@FreeBSD.org; Sat, 30 Jul 2016 11:17:36 GMT (envelope-from iateaca@FreeBSD.org) Date: Sat, 30 Jul 2016 11:17:36 GMT Message-Id: <201607301117.u6UBHatY033099@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to iateaca@FreeBSD.org using -f From: iateaca@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r306987 - soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 30 Jul 2016 11:17:37 -0000 Author: iateaca Date: Sat Jul 30 11:17:36 2016 New Revision: 306987 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=306987 Log: support samples of 24bit remove support for 8bit stamples M bhyve/hda_codec.c Modified: soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/hda_codec.c Modified: soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/hda_codec.c ============================================================================== --- soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/hda_codec.c Sat Jul 30 10:32:28 2016 (r306986) +++ soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/hda_codec.c Sat Jul 30 11:17:36 2016 (r306987) @@ -41,6 +41,7 @@ #define HDA_CODEC_FMT_BITS_MASK (0x07 << 4) #define HDA_CODEC_FMT_BITS_8 (0x00 << 4) #define HDA_CODEC_FMT_BITS_16 (0x01 << 4) +#define HDA_CODEC_FMT_BITS_24 (0x03 << 4) #define HDA_CODEC_FMT_BITS_32 (0x04 << 4) #define HDA_CODEC_FMT_CHAN_MASK (0x0f << 0) @@ -188,7 +189,7 @@ HDA_CODEC_AUDIO_WCAP_AMP_OVR | HDA_CODEC_AUDIO_WCAP_OUT_AMP | HDA_CODEC_AUDIO_WCAP_STEREO, - [HDA_PARAM_SUPP_PCM_SIZE_RATE] = (0x1f << 16) | 0x7ff, /* B8 - B32, 8.0 - 192.0kHz */ + [HDA_PARAM_SUPP_PCM_SIZE_RATE] = (0x1a << 16) | 0x7ff, /* B16, B24, B32; 8.0 - 192.0kHz */ [HDA_PARAM_SUPP_STREAM_FORMATS] = HDA_CODEC_SUPP_STREAM_FORMATS_PCM, [HDA_PARAM_INPUT_AMP_CAP] = 0x00, /* None */ [HDA_PARAM_CONN_LIST_LENGTH] = 0x00, @@ -445,6 +446,9 @@ case HDA_CODEC_FMT_BITS_16: params->format = AFMT_S16_LE; break; + case HDA_CODEC_FMT_BITS_24: + params->format = AFMT_S24_LE; + break; case HDA_CODEC_FMT_BITS_32: params->format = AFMT_S32_LE; break; From owner-svn-soc-all@freebsd.org Sat Jul 30 14:38:11 2016 Return-Path: Delivered-To: svn-soc-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id CA6BEBA88C1 for ; Sat, 30 Jul 2016 14:38:11 +0000 (UTC) (envelope-from iateaca@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id AF5C91D51 for ; Sat, 30 Jul 2016 14:38:11 +0000 (UTC) (envelope-from iateaca@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.15.2/8.15.2) with ESMTP id u6UEcBGJ009994 for ; Sat, 30 Jul 2016 14:38:11 GMT (envelope-from iateaca@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.15.2/8.15.2/Submit) id u6UEcB2q009965 for svn-soc-all@FreeBSD.org; Sat, 30 Jul 2016 14:38:11 GMT (envelope-from iateaca@FreeBSD.org) Date: Sat, 30 Jul 2016 14:38:11 GMT Message-Id: <201607301438.u6UEcB2q009965@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to iateaca@FreeBSD.org using -f From: iateaca@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r306988 - soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 30 Jul 2016 14:38:11 -0000 Author: iateaca Date: Sat Jul 30 14:38:10 2016 New Revision: 306988 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=306988 Log: add one audio input node and one pin widget line-in nodes M bhyve/hda_codec.c Modified: soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/hda_codec.c Modified: soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/hda_codec.c ============================================================================== --- soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/hda_codec.c Sat Jul 30 11:17:36 2016 (r306987) +++ soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/hda_codec.c Sat Jul 30 14:38:10 2016 (r306988) @@ -16,9 +16,12 @@ #define HDA_CODEC_FG_NID 0x01 #define HDA_CODEC_AUDIO_OUTPUT_NID 0x02 #define HDA_CODEC_PIN_OUTPUT_NID 0x03 +#define HDA_CODEC_AUDIO_INPUT_NID 0x04 +#define HDA_CODEC_PIN_INPUT_NID 0x05 -#define HDA_CODEC_STREAMS_COUNT 0x01 +#define HDA_CODEC_STREAMS_COUNT 0x02 #define HDA_CODEC_STREAM_OUTPUT 0x00 +#define HDA_CODEC_STREAM_INPUT 0x01 #define HDA_CODEC_PARAMS_COUNT 0x14 #define HDA_CODEC_CONN_LIST_COUNT 0x01 @@ -47,14 +50,17 @@ #define HDA_CODEC_FMT_CHAN_MASK (0x0f << 0) #define HDA_CODEC_AUDIO_WCAP_OUTPUT (0x00 << HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_SHIFT) +#define HDA_CODEC_AUDIO_WCAP_INPUT (0x01 << HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_SHIFT) #define HDA_CODEC_AUDIO_WCAP_PIN (0x04 << HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_SHIFT) #define HDA_CODEC_AUDIO_WCAP_CONN_LIST (1 << HDA_PARAM_AUDIO_WIDGET_CAP_CONN_LIST_SHIFT) #define HDA_CODEC_AUDIO_WCAP_FORMAT_OVR (1 << HDA_PARAM_AUDIO_WIDGET_CAP_FORMAT_OVR_SHIFT) #define HDA_CODEC_AUDIO_WCAP_AMP_OVR (1 << HDA_PARAM_AUDIO_WIDGET_CAP_AMP_OVR_SHIFT) #define HDA_CODEC_AUDIO_WCAP_OUT_AMP (1 << HDA_PARAM_AUDIO_WIDGET_CAP_OUT_AMP_SHIFT) +#define HDA_CODEC_AUDIO_WCAP_IN_AMP (1 << HDA_PARAM_AUDIO_WIDGET_CAP_IN_AMP_SHIFT) #define HDA_CODEC_AUDIO_WCAP_STEREO (1 << HDA_PARAM_AUDIO_WIDGET_CAP_STEREO_SHIFT) #define HDA_CODEC_PIN_CAP_OUTPUT (1 << HDA_PARAM_PIN_CAP_OUTPUT_CAP_SHIFT) +#define HDA_CODEC_PIN_CAP_INPUT (1 << HDA_PARAM_PIN_CAP_INPUT_CAP_SHIFT) #define HDA_CODEC_PIN_CAP_PRESENCE_DETECT (1 << HDA_PARAM_PIN_CAP_PRESENCE_DETECT_CAP_SHIFT) #define HDA_CODEC_OUTPUT_AMP_CAP_MUTE_CAP (1 << HDA_PARAM_OUTPUT_AMP_CAP_MUTE_CAP_SHIFT) @@ -67,8 +73,10 @@ #define HDA_CODEC_PIN_SENSE_PRESENCE_PLUGGED (1 << 31) #define HDA_CODEC_PIN_WIDGET_CTRL_OUT_ENABLE (1 << HDA_CMD_GET_PIN_WIDGET_CTRL_OUT_ENABLE_SHIFT) +#define HDA_CODEC_PIN_WIDGET_CTRL_IN_ENABLE (1 << HDA_CMD_GET_PIN_WIDGET_CTRL_IN_ENABLE_SHIFT) #define HDA_CONFIG_DEFAULTCONF_COLOR_BLACK (0x01 << HDA_CONFIG_DEFAULTCONF_COLOR_SHIFT) +#define HDA_CONFIG_DEFAULTCONF_COLOR_RED (0x05 << HDA_CONFIG_DEFAULTCONF_COLOR_SHIFT) #define HDA_CODEC_BUF_SIZE HDA_FIFO_SIZE @@ -175,7 +183,7 @@ [HDA_PARAM_SUB_NODE_COUNT] = 0x00010001, /* 1 Subnode, StartNid = 1 */ }, [HDA_CODEC_FG_NID] = { - [HDA_PARAM_SUB_NODE_COUNT] = 0x00020002, /* 2 Subnodes, StartNid = 2 */ + [HDA_PARAM_SUB_NODE_COUNT] = 0x00020004, /* 4 Subnodes, StartNid = 2 */ [HDA_PARAM_FCT_GRP_TYPE] = HDA_PARAM_FCT_GRP_TYPE_NODE_TYPE_AUDIO, [HDA_PARAM_SUPP_PCM_SIZE_RATE] = (0x1f << 16) | 0x7ff, /* B8 - B32, 8.0 - 192.0kHz */ [HDA_PARAM_SUPP_STREAM_FORMATS] = HDA_CODEC_SUPP_STREAM_FORMATS_PCM, @@ -189,7 +197,7 @@ HDA_CODEC_AUDIO_WCAP_AMP_OVR | HDA_CODEC_AUDIO_WCAP_OUT_AMP | HDA_CODEC_AUDIO_WCAP_STEREO, - [HDA_PARAM_SUPP_PCM_SIZE_RATE] = (0x1a << 16) | 0x7ff, /* B16, B24, B32; 8.0 - 192.0kHz */ + [HDA_PARAM_SUPP_PCM_SIZE_RATE] = (0x02 << 16) | 0x7fc, /* B16, 16.0 - 192.0kHz */ [HDA_PARAM_SUPP_STREAM_FORMATS] = HDA_CODEC_SUPP_STREAM_FORMATS_PCM, [HDA_PARAM_INPUT_AMP_CAP] = 0x00, /* None */ [HDA_PARAM_CONN_LIST_LENGTH] = 0x00, @@ -208,12 +216,37 @@ [HDA_PARAM_CONN_LIST_LENGTH] = 0x01, [HDA_PARAM_OUTPUT_AMP_CAP] = 0x00, /* None */ }, + [HDA_CODEC_AUDIO_INPUT_NID] = { + [HDA_PARAM_AUDIO_WIDGET_CAP] = HDA_CODEC_AUDIO_WCAP_INPUT | + HDA_CODEC_AUDIO_WCAP_CONN_LIST | + HDA_CODEC_AUDIO_WCAP_FORMAT_OVR | + HDA_CODEC_AUDIO_WCAP_AMP_OVR | + HDA_CODEC_AUDIO_WCAP_IN_AMP | + HDA_CODEC_AUDIO_WCAP_STEREO, + [HDA_PARAM_SUPP_PCM_SIZE_RATE] = (0x02 << 16) | 0x7fc, /* B16, 16.0 - 192.0kHz */ + [HDA_PARAM_SUPP_STREAM_FORMATS] = HDA_CODEC_SUPP_STREAM_FORMATS_PCM, + [HDA_PARAM_OUTPUT_AMP_CAP] = 0x00, /* None */ + [HDA_PARAM_CONN_LIST_LENGTH] = 0x01, + [HDA_PARAM_INPUT_AMP_CAP] = HDA_CODEC_OUTPUT_AMP_CAP_MUTE_CAP | + HDA_CODEC_OUTPUT_AMP_CAP_STEPSIZE | + HDA_CODEC_OUTPUT_AMP_CAP_NUMSTEPS | + HDA_CODEC_OUTPUT_AMP_CAP_OFFSET, + }, + [HDA_CODEC_PIN_INPUT_NID] = { + [HDA_PARAM_AUDIO_WIDGET_CAP] = HDA_CODEC_AUDIO_WCAP_PIN | + HDA_CODEC_AUDIO_WCAP_STEREO, + [HDA_PARAM_PIN_CAP] = HDA_CODEC_PIN_CAP_INPUT | + HDA_CODEC_PIN_CAP_PRESENCE_DETECT, + [HDA_PARAM_INPUT_AMP_CAP] = 0x00, /* None */ + [HDA_PARAM_OUTPUT_AMP_CAP] = 0x00, /* None */ + }, }; #define HDA_CODEC_NODES_COUNT (ARRAY_SIZE(hda_codec_parameters)) static const uint8_t hda_codec_conn_list[HDA_CODEC_NODES_COUNT][HDA_CODEC_CONN_LIST_COUNT] = { - [HDA_CODEC_PIN_OUTPUT_NID] = {0x02}, + [HDA_CODEC_PIN_OUTPUT_NID] = {HDA_CODEC_AUDIO_OUTPUT_NID}, + [HDA_CODEC_AUDIO_INPUT_NID] = {HDA_CODEC_PIN_INPUT_NID}, }; static const uint32_t hda_codec_conf_default[HDA_CODEC_NODES_COUNT] = { @@ -221,10 +254,15 @@ HDA_CONFIG_DEFAULTCONF_DEVICE_LINE_OUT | HDA_CONFIG_DEFAULTCONF_COLOR_BLACK | (0x01 << HDA_CONFIG_DEFAULTCONF_ASSOCIATION_SHIFT), + [HDA_CODEC_PIN_INPUT_NID] = HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_JACK | + HDA_CONFIG_DEFAULTCONF_DEVICE_LINE_IN | + HDA_CONFIG_DEFAULTCONF_COLOR_RED | + (0x02 << HDA_CONFIG_DEFAULTCONF_ASSOCIATION_SHIFT), }; static const uint8_t hda_codec_pin_ctrl_default[HDA_CODEC_NODES_COUNT] = { [HDA_CODEC_PIN_OUTPUT_NID] = HDA_CODEC_PIN_WIDGET_CTRL_OUT_ENABLE, + [HDA_CODEC_PIN_INPUT_NID] = HDA_CODEC_PIN_WIDGET_CTRL_IN_ENABLE, }; static const verb_func_t hda_codec_verb_handlers[HDA_CODEC_NODES_COUNT] = { From owner-svn-soc-all@freebsd.org Sat Jul 30 20:37:04 2016 Return-Path: Delivered-To: svn-soc-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 5FE1CBA8C63 for ; Sat, 30 Jul 2016 20:37:04 +0000 (UTC) (envelope-from iateaca@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 42A521E97 for ; Sat, 30 Jul 2016 20:37:04 +0000 (UTC) (envelope-from iateaca@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.15.2/8.15.2) with ESMTP id u6UKb4xM041899 for ; Sat, 30 Jul 2016 20:37:04 GMT (envelope-from iateaca@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.15.2/8.15.2/Submit) id u6UKb2MT041822 for svn-soc-all@FreeBSD.org; Sat, 30 Jul 2016 20:37:02 GMT (envelope-from iateaca@FreeBSD.org) Date: Sat, 30 Jul 2016 20:37:02 GMT Message-Id: <201607302037.u6UKb2MT041822@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to iateaca@FreeBSD.org using -f From: iateaca@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r306995 - soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 30 Jul 2016 20:37:04 -0000 Author: iateaca Date: Sat Jul 30 20:37:01 2016 New Revision: 306995 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=306995 Log: implement audio_record - records samples from the sound device using blocking operations add suport for input stream in hda_codec (implement hda_codec_audio_input_nid, hda_codec_audio_input_do_transfer, hda_codec_audio_input_do_setup) if hda_transfer is called with stream=0 return error(it means the stream has been stopped) M bhyve/audio.c M bhyve/audio.h M bhyve/hda_codec.c M bhyve/pci_hda.c Modified: soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/audio.c soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/audio.h soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/hda_codec.c soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/pci_hda.c Modified: soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/audio.c ============================================================================== --- soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/audio.c Sat Jul 30 19:03:32 2016 (r306994) +++ soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/audio.c Sat Jul 30 20:37:01 2016 (r306995) @@ -161,3 +161,36 @@ return 0; } +/* + * audio_record - records samples from the sound device using blocking operations + * @aud - the audio player used to capture the samples + * @buf - the buffer to receive the samples + * @count - the number of bytes to capture in buffer + * Returns -1 on error and 0 on success + */ +int audio_record(struct audio *aud, void *buf, size_t count) +{ + int audio_fd = -1; + ssize_t len = 0, total = 0; + + assert(aud); + assert(!aud->dir); + assert(buf); + + audio_fd = aud->fd; + assert(audio_fd != -1); + + total = 0; + while (total < count) { + len = read(audio_fd, buf + total, count - total); + if (len == -1) { + DPRINTF("Fail to write to fd: %d, errno: %d\n", audio_fd, errno); + return -1; + } + + total += len; + } + + return 0; +} + Modified: soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/audio.h ============================================================================== --- soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/audio.h Sat Jul 30 19:03:32 2016 (r306994) +++ soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/audio.h Sat Jul 30 20:37:01 2016 (r306995) @@ -46,4 +46,13 @@ */ int audio_playback(struct audio *aud, const void *buf, size_t count); +/* + * audio_record - records samples from the sound device using blocking operations + * @aud - the audio player used to capture the samples + * @buf - the buffer to receive the samples + * @count - the number of bytes to capture in buffer + * Returns -1 on error and 0 on success + */ +int audio_record(struct audio *aud, void *buf, size_t count); + #endif /* _AUDIO_EMUL_H_ */ Modified: soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/hda_codec.c ============================================================================== --- soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/hda_codec.c Sat Jul 30 19:03:32 2016 (r306994) +++ soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/hda_codec.c Sat Jul 30 20:37:01 2016 (r306995) @@ -171,6 +171,15 @@ hda_codec_audio_output_do_transfer(void *arg); static int hda_codec_audio_output_do_setup(void *arg); +static uint32_t +hda_codec_audio_input_nid(struct hda_codec_softc *sc, uint16_t verb, uint16_t payload); +static void +hda_codec_audio_input_do_transfer(void *arg); +static int +hda_codec_audio_input_do_setup(void *arg); + +static uint32_t +hda_codec_audio_inout_nid(struct hda_codec_stream *st, uint16_t verb, uint16_t payload); /* * HDA Codec global data @@ -267,6 +276,7 @@ static const verb_func_t hda_codec_verb_handlers[HDA_CODEC_NODES_COUNT] = { [HDA_CODEC_AUDIO_OUTPUT_NID] = hda_codec_audio_output_nid, + [HDA_CODEC_AUDIO_INPUT_NID] = hda_codec_audio_input_nid, }; /* @@ -295,6 +305,9 @@ sc->verb_handlers = hda_codec_verb_handlers; DPRINTF("HDA Codec nodes: %d\n", sc->no_nodes); + /* + * Initialize the Audio Output stream + */ st = &sc->streams[HDA_CODEC_STREAM_OUTPUT]; err = hda_audio_ctxt_init(&st->actx, "hda-audio-output", hda_codec_audio_output_do_transfer, hda_codec_audio_output_do_setup, sc); @@ -307,6 +320,21 @@ return -1; } + /* + * Initialize the Audio Input stream + */ + st = &sc->streams[HDA_CODEC_STREAM_INPUT]; + + err = hda_audio_ctxt_init(&st->actx, "hda-audio-input", hda_codec_audio_input_do_transfer, hda_codec_audio_input_do_setup, sc); + assert(!err); + + /* TODO Get the name of the sound device from the config string */ + st->aud = audio_init("/dev/dsp", 0); + if (!st->aud) { + DPRINTF("Fail to init the input audio player\n"); + return -1; + } + sc->hci = hci; hci->priv = sc; @@ -319,6 +347,7 @@ struct hda_ops *hops = NULL; struct hda_codec_softc *sc = NULL; struct hda_codec_stream *st = NULL; + int i; assert(hci); @@ -328,11 +357,13 @@ sc = (struct hda_codec_softc *)hci->priv; assert(sc); - st = &sc->streams[HDA_CODEC_STREAM_OUTPUT]; - st->left_gain = HDA_CODEC_AMP_NUMSTEPS; - st->right_gain = HDA_CODEC_AMP_NUMSTEPS; - st->left_mute = HDA_CODEC_SET_AMP_GAIN_MUTE_MUTE; - st->right_mute = HDA_CODEC_SET_AMP_GAIN_MUTE_MUTE; + for (i = 0; i < HDA_CODEC_STREAMS_COUNT; i++) { + st = &sc->streams[i]; + st->left_gain = HDA_CODEC_AMP_NUMSTEPS; + st->right_gain = HDA_CODEC_AMP_NUMSTEPS; + st->left_mute = HDA_CODEC_SET_AMP_GAIN_MUTE_MUTE; + st->right_mute = HDA_CODEC_SET_AMP_GAIN_MUTE_MUTE; + } DPRINTF("cad: 0x%x\n", hci->cad); @@ -420,28 +451,28 @@ struct hda_codec_softc *sc = NULL; struct hda_codec_stream *st = NULL; struct hda_audio_ctxt *actx = NULL; + int i; int err; assert(hci); + assert(stream); sc = (struct hda_codec_softc *)hci->priv; assert(sc); - /* TODO search the right stream - * For now, there is only one stream - */ - st = &sc->streams[HDA_CODEC_STREAM_OUTPUT]; + for (i = 0; i < HDA_CODEC_STREAMS_COUNT; i++) { + st = &sc->streams[i]; + if (st->stream == stream) + break; + } DPRINTF("run: %d, stream: 0x%x, st->stream: 0x%x dir: %d\n", run, stream, st->stream, dir); - if (!st->stream) { - DPRINTF("Stream not set\n"); + if (stream != st->stream) { + DPRINTF("Stream not found\n"); return 0; } - if (stream != st->stream) - return -1; - actx = &st->actx; if (run) @@ -504,15 +535,132 @@ static uint32_t hda_codec_audio_output_nid(struct hda_codec_softc *sc, uint16_t verb, uint16_t payload) { + struct hda_codec_stream *st = &sc->streams[HDA_CODEC_STREAM_OUTPUT]; + int res; + + res = hda_codec_audio_inout_nid(st, verb, payload); + + return res; +} + +static void +hda_codec_audio_output_do_transfer(void *arg) +{ + struct hda_codec_softc *sc = (struct hda_codec_softc *)arg; + struct hda_codec_inst *hci = NULL; + struct hda_ops *hops = NULL; + struct hda_codec_stream *st = NULL; + struct audio *aud = NULL; + int err; + + hci = sc->hci; + assert(hci); + + hops = hci->hops; + assert(hops); + + st = &sc->streams[HDA_CODEC_STREAM_OUTPUT]; + aud = st->aud; + + err = hops->transfer(hci, st->stream, 1, st->buf, sizeof(st->buf)); + if (err) + return; + + err = audio_playback(aud, st->buf, sizeof(st->buf)); + assert(!err); + + return; +} + +static int +hda_codec_audio_output_do_setup(void *arg) +{ + struct hda_codec_softc *sc = (struct hda_codec_softc *)arg; + struct hda_codec_stream *st = NULL; + struct audio *aud = NULL; + struct audio_params params; + int err; + + st = &sc->streams[HDA_CODEC_STREAM_OUTPUT]; + aud = st->aud; + + err = hda_codec_parse_format(st->fmt, ¶ms); + if (err) + return -1; + + DPRINTF("rate: %d, channels: %d, format: 0x%x\n", params.rate, params.channels, params.format); + + return audio_set_params(aud, ¶ms); +} + +static uint32_t +hda_codec_audio_input_nid(struct hda_codec_softc *sc, uint16_t verb, uint16_t payload) +{ + struct hda_codec_stream *st = &sc->streams[HDA_CODEC_STREAM_INPUT]; + int res; + + res = hda_codec_audio_inout_nid(st, verb, payload); + + return res; +} + +static void +hda_codec_audio_input_do_transfer(void *arg) +{ + struct hda_codec_softc *sc = (struct hda_codec_softc *)arg; + struct hda_codec_inst *hci = NULL; + struct hda_ops *hops = NULL; + struct hda_codec_stream *st = NULL; + struct audio *aud = NULL; + int err; + + hci = sc->hci; + assert(hci); + + hops = hci->hops; + assert(hops); + + st = &sc->streams[HDA_CODEC_STREAM_INPUT]; + aud = st->aud; + + err = audio_record(aud, st->buf, sizeof(st->buf)); + assert(!err); + + hops->transfer(hci, st->stream, 0, st->buf, sizeof(st->buf)); + + return; +} + +static int +hda_codec_audio_input_do_setup(void *arg) +{ + struct hda_codec_softc *sc = (struct hda_codec_softc *)arg; struct hda_codec_stream *st = NULL; + struct audio *aud = NULL; + struct audio_params params; + int err; + + st = &sc->streams[HDA_CODEC_STREAM_INPUT]; + aud = st->aud; + + err = hda_codec_parse_format(st->fmt, ¶ms); + if (err) + return -1; + + DPRINTF("rate: %d, channels: %d, format: 0x%x\n", params.rate, params.channels, params.format); + + return audio_set_params(aud, ¶ms); +} + +static uint32_t +hda_codec_audio_inout_nid(struct hda_codec_stream *st, uint16_t verb, uint16_t payload) +{ uint32_t res = 0; uint8_t mute = 0; uint8_t gain = 0; DPRINTF("verb: 0x%x, payload, 0x%x\n", verb, payload); - st = &sc->streams[HDA_CODEC_STREAM_OUTPUT]; - switch (verb) { case HDA_CMD_VERB_GET_CONV_FMT: res = st->fmt; @@ -521,7 +669,6 @@ st->fmt = payload; break; case HDA_CMD_VERB_GET_AMP_GAIN_MUTE: - assert(payload & HDA_CMD_GET_AMP_GAIN_MUTE_OUTPUT); if (payload & HDA_CMD_GET_AMP_GAIN_MUTE_LEFT) { res = st->left_gain | st->left_mute; DPRINTF("GET_AMP_GAIN_MUTE_LEFT: 0x%x\n", res); @@ -531,8 +678,6 @@ } break; case HDA_CMD_VERB_SET_AMP_GAIN_MUTE: - assert(payload & HDA_CMD_SET_AMP_GAIN_MUTE_OUTPUT); - mute = payload & HDA_CODEC_SET_AMP_GAIN_MUTE_MUTE; gain = payload & HDA_CODEC_SET_AMP_GAIN_MUTE_GAIN_MASK; @@ -566,56 +711,6 @@ return res; } -static void -hda_codec_audio_output_do_transfer(void *arg) -{ - struct hda_codec_softc *sc = (struct hda_codec_softc *)arg; - struct hda_codec_inst *hci = NULL; - struct hda_ops *hops = NULL; - struct hda_codec_stream *st = NULL; - struct audio *aud = NULL; - int err; - - hci = sc->hci; - assert(hci); - - hops = hci->hops; - assert(hops); - - st = &sc->streams[HDA_CODEC_STREAM_OUTPUT]; - aud = st->aud; - - err = hops->transfer(hci, st->stream, 1, st->buf, sizeof(st->buf)); - if (err) - return; - - err = audio_playback(aud, st->buf, sizeof(st->buf)); - assert(!err); - - return; -} - -static int -hda_codec_audio_output_do_setup(void *arg) -{ - struct hda_codec_softc *sc = (struct hda_codec_softc *)arg; - struct hda_codec_stream *st = NULL; - struct audio *aud = NULL; - struct audio_params params; - int err; - - st = &sc->streams[HDA_CODEC_STREAM_OUTPUT]; - aud = st->aud; - - err = hda_codec_parse_format(st->fmt, ¶ms); - if (err) - return -1; - - DPRINTF("rate: %d, channels: %d, format: 0x%x\n", params.rate, params.channels, params.format); - - return audio_set_params(aud, ¶ms); -} - struct hda_codec_class hda_codec = { .name = "hda_codec", .init = hda_codec_init, Modified: soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/pci_hda.c ============================================================================== --- soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/pci_hda.c Sat Jul 30 19:03:32 2016 (r306994) +++ soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/pci_hda.c Sat Jul 30 20:37:01 2016 (r306995) @@ -1112,6 +1112,11 @@ assert(buf); assert(!(count % HDA_DMA_ACCESS_LEN)); + if (!stream) { + DPRINTF("Invalid stream\n"); + return -1; + } + sc = hci->hda; assert(stream < HDA_STREAM_TAGS_CNT);