From owner-svn-src-stable-9@freebsd.org Mon Jun 27 22:18:53 2016 Return-Path: Delivered-To: svn-src-stable-9@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 E7475B8559E; Mon, 27 Jun 2016 22:18:53 +0000 (UTC) (envelope-from bdrewery@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (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 B685D2692; Mon, 27 Jun 2016 22:18:53 +0000 (UTC) (envelope-from bdrewery@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u5RMIq4N039831; Mon, 27 Jun 2016 22:18:52 GMT (envelope-from bdrewery@FreeBSD.org) Received: (from bdrewery@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u5RMIqpk039829; Mon, 27 Jun 2016 22:18:52 GMT (envelope-from bdrewery@FreeBSD.org) Message-Id: <201606272218.u5RMIqpk039829@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: bdrewery set sender to bdrewery@FreeBSD.org using -f From: Bryan Drewery Date: Mon, 27 Jun 2016 22:18:52 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org Subject: svn commit: r302240 - in stable/9: share/man/man4 sys/dev/filemon X-SVN-Group: stable-9 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-9@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for only the 9-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 27 Jun 2016 22:18:54 -0000 Author: bdrewery Date: Mon Jun 27 22:18:52 2016 New Revision: 302240 URL: https://svnweb.freebsd.org/changeset/base/302240 Log: Mark filemon(4) as "experimental" for 9 since it has many unfixed stability, performance, and audit issues that have not been MFC'd. Modified: stable/9/share/man/man4/filemon.4 stable/9/sys/dev/filemon/filemon.c Modified: stable/9/share/man/man4/filemon.4 ============================================================================== --- stable/9/share/man/man4/filemon.4 Mon Jun 27 22:13:43 2016 (r302239) +++ stable/9/share/man/man4/filemon.4 Mon Jun 27 22:18:52 2016 (r302240) @@ -211,3 +211,7 @@ does not make sense to have daemons for. .Pp Unloading the module may panic the system, thus requires using .Ic kldunload -f . +.Pp +.Nm +is still experimental with +.Fx 9 . Modified: stable/9/sys/dev/filemon/filemon.c ============================================================================== --- stable/9/sys/dev/filemon/filemon.c Mon Jun 27 22:13:43 2016 (r302239) +++ stable/9/sys/dev/filemon/filemon.c Mon Jun 27 22:18:52 2016 (r302240) @@ -291,6 +291,7 @@ filemon_modevent(module_t mod __unused, switch (type) { case MOD_LOAD: + printf("WARNING: Filemon is still experimental for FreeBSD 9.\n"); filemon_load(data); break; From owner-svn-src-stable-9@freebsd.org Wed Jun 29 10:23:20 2016 Return-Path: Delivered-To: svn-src-stable-9@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 E2DCEB8440F; Wed, 29 Jun 2016 10:23:20 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (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 BE9DD200D; Wed, 29 Jun 2016 10:23:20 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u5TANJK1053772; Wed, 29 Jun 2016 10:23:19 GMT (envelope-from hselasky@FreeBSD.org) Received: (from hselasky@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u5TANJLX053769; Wed, 29 Jun 2016 10:23:19 GMT (envelope-from hselasky@FreeBSD.org) Message-Id: <201606291023.u5TANJLX053769@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: hselasky set sender to hselasky@FreeBSD.org using -f From: Hans Petter Selasky Date: Wed, 29 Jun 2016 10:23:19 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org Subject: svn commit: r302267 - stable/9/sys/dev/usb/controller X-SVN-Group: stable-9 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-9@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for only the 9-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 29 Jun 2016 10:23:21 -0000 Author: hselasky Date: Wed Jun 29 10:23:19 2016 New Revision: 302267 URL: https://svnweb.freebsd.org/changeset/base/302267 Log: MFC r302076: Update the definition for number of scratch pages to match the latest version of the XHCI specification. Make sure the code can handle the maximum number of allowed scratch pages. Submitted by: Shichun_Ma@Dell.com Modified: stable/9/sys/dev/usb/controller/xhci.c stable/9/sys/dev/usb/controller/xhci.h stable/9/sys/dev/usb/controller/xhcireg.h Directory Properties: stable/9/sys/ (props changed) stable/9/sys/dev/ (props changed) Modified: stable/9/sys/dev/usb/controller/xhci.c ============================================================================== --- stable/9/sys/dev/usb/controller/xhci.c Wed Jun 29 10:21:45 2016 (r302266) +++ stable/9/sys/dev/usb/controller/xhci.c Wed Jun 29 10:23:19 2016 (r302267) @@ -204,7 +204,7 @@ static void xhci_iterate_hw_softc(struct usb_bus *bus, usb_bus_mem_sub_cb_t *cb) { struct xhci_softc *sc = XHCI_BUS2SC(bus); - uint8_t i; + uint16_t i; cb(bus, &sc->sc_hw.root_pc, &sc->sc_hw.root_pg, sizeof(struct xhci_hw_root), XHCI_PAGE_SIZE); @@ -212,7 +212,7 @@ xhci_iterate_hw_softc(struct usb_bus *bu cb(bus, &sc->sc_hw.ctx_pc, &sc->sc_hw.ctx_pg, sizeof(struct xhci_dev_ctx_addr), XHCI_PAGE_SIZE); - for (i = 0; i != XHCI_MAX_SCRATCHPADS; i++) { + for (i = 0; i != sc->sc_noscratch; i++) { cb(bus, &sc->sc_hw.scratch_pc[i], &sc->sc_hw.scratch_pg[i], XHCI_PAGE_SIZE, XHCI_PAGE_SIZE); } Modified: stable/9/sys/dev/usb/controller/xhci.h ============================================================================== --- stable/9/sys/dev/usb/controller/xhci.h Wed Jun 29 10:21:45 2016 (r302266) +++ stable/9/sys/dev/usb/controller/xhci.h Wed Jun 29 10:23:19 2016 (r302267) @@ -30,7 +30,7 @@ #define XHCI_MAX_DEVICES MIN(USB_MAX_DEVICES, 128) #define XHCI_MAX_ENDPOINTS 32 /* hardcoded - do not change */ -#define XHCI_MAX_SCRATCHPADS 32 +#define XHCI_MAX_SCRATCHPADS 1024 #define XHCI_MAX_EVENTS (16 * 13) #define XHCI_MAX_COMMANDS (16 * 1) #define XHCI_MAX_RSEG 1 @@ -486,14 +486,15 @@ struct xhci_softc { uint16_t sc_command_idx; uint16_t sc_imod_default; + /* number of scratch pages */ + uint16_t sc_noscratch; + uint8_t sc_event_ccs; uint8_t sc_command_ccs; /* number of XHCI device slots */ uint8_t sc_noslot; /* number of ports on root HUB */ uint8_t sc_noport; - /* number of scratch pages */ - uint8_t sc_noscratch; /* root HUB device configuration */ uint8_t sc_conf; /* root HUB port event bitmap, max 256 ports */ Modified: stable/9/sys/dev/usb/controller/xhcireg.h ============================================================================== --- stable/9/sys/dev/usb/controller/xhcireg.h Wed Jun 29 10:21:45 2016 (r302266) +++ stable/9/sys/dev/usb/controller/xhcireg.h Wed Jun 29 10:23:19 2016 (r302267) @@ -52,8 +52,8 @@ #define XHCI_HCSPARAMS2 0x08 /* RO structual parameters 2 */ #define XHCI_HCS2_IST(x) ((x) & 0xF) #define XHCI_HCS2_ERST_MAX(x) (((x) >> 4) & 0xF) -#define XHCI_HCS2_SPR(x) (((x) >> 24) & 0x1) -#define XHCI_HCS2_SPB_MAX(x) (((x) >> 27) & 0x7F) +#define XHCI_HCS2_SPR(x) (((x) >> 26) & 0x1) +#define XHCI_HCS2_SPB_MAX(x) ((((x) >> 16) & 0x3E0) | (((x) >> 27) & 0x1F)) #define XHCI_HCSPARAMS3 0x0C /* RO structual parameters 3 */ #define XHCI_HCS3_U1_DEL(x) ((x) & 0xFF) #define XHCI_HCS3_U2_DEL(x) (((x) >> 16) & 0xFFFF) From owner-svn-src-stable-9@freebsd.org Wed Jun 29 10:46:12 2016 Return-Path: Delivered-To: svn-src-stable-9@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 2C32BB84B67; Wed, 29 Jun 2016 10:46:12 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (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 E295620A4; Wed, 29 Jun 2016 10:46:11 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u5TAkBBD061404; Wed, 29 Jun 2016 10:46:11 GMT (envelope-from hselasky@FreeBSD.org) Received: (from hselasky@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u5TAkBTs061403; Wed, 29 Jun 2016 10:46:11 GMT (envelope-from hselasky@FreeBSD.org) Message-Id: <201606291046.u5TAkBTs061403@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: hselasky set sender to hselasky@FreeBSD.org using -f From: Hans Petter Selasky Date: Wed, 29 Jun 2016 10:46:11 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org Subject: svn commit: r302273 - stable/9/lib/libusb X-SVN-Group: stable-9 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-9@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for only the 9-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 29 Jun 2016 10:46:12 -0000 Author: hselasky Date: Wed Jun 29 10:46:10 2016 New Revision: 302273 URL: https://svnweb.freebsd.org/changeset/base/302273 Log: MFC r301842: Implement code to stop all USB endpoints before executing a USB device reset command, alternate setting command or set configuration command. Else LibUSB v1.0 will not re-open the endpoints which the kernel closes and the USB application might wait infinitely for transfers to complete. Modified: stable/9/lib/libusb/libusb10.c Directory Properties: stable/9/lib/ (props changed) stable/9/lib/libusb/ (props changed) Modified: stable/9/lib/libusb/libusb10.c ============================================================================== --- stable/9/lib/libusb/libusb10.c Wed Jun 29 10:43:31 2016 (r302272) +++ stable/9/lib/libusb/libusb10.c Wed Jun 29 10:46:10 2016 (r302273) @@ -45,6 +45,8 @@ #include "libusb.h" #include "libusb10.h" +#define LIBUSB_NUM_SW_ENDPOINTS (16 * 4) + static pthread_mutex_t default_context_lock = PTHREAD_MUTEX_INITIALIZER; struct libusb_context *usbi_default_context = NULL; @@ -436,7 +438,7 @@ libusb_open(libusb_device *dev, libusb_d if (dev == NULL) return (LIBUSB_ERROR_INVALID_PARAM); - err = libusb20_dev_open(pdev, 16 * 4 /* number of endpoints */ ); + err = libusb20_dev_open(pdev, LIBUSB_NUM_SW_ENDPOINTS); if (err) { libusb_unref_device(dev); return (LIBUSB_ERROR_NO_MEM); @@ -1489,7 +1491,17 @@ libusb_cancel_transfer(struct libusb_tra UNEXPORTED void libusb10_cancel_all_transfer(libusb_device *dev) { - /* TODO */ + struct libusb20_device *pdev = dev->os_priv; + unsigned x; + + for (x = 0; x != LIBUSB_NUM_SW_ENDPOINTS; x++) { + struct libusb20_transfer *xfer; + + xfer = libusb20_tr_get_pointer(pdev, x); + if (xfer == NULL) + continue; + libusb20_tr_close(xfer); + } } uint16_t From owner-svn-src-stable-9@freebsd.org Wed Jun 29 11:06:15 2016 Return-Path: Delivered-To: svn-src-stable-9@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 42733B8510B; Wed, 29 Jun 2016 11:06:15 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (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 0D6CD2CD1; Wed, 29 Jun 2016 11:06:14 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u5TB6E53068845; Wed, 29 Jun 2016 11:06:14 GMT (envelope-from hselasky@FreeBSD.org) Received: (from hselasky@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u5TB6DIe068837; Wed, 29 Jun 2016 11:06:13 GMT (envelope-from hselasky@FreeBSD.org) Message-Id: <201606291106.u5TB6DIe068837@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: hselasky set sender to hselasky@FreeBSD.org using -f From: Hans Petter Selasky Date: Wed, 29 Jun 2016 11:06:13 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org Subject: svn commit: r302276 - stable/9/lib/libusb X-SVN-Group: stable-9 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-9@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for only the 9-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 29 Jun 2016 11:06:15 -0000 Author: hselasky Date: Wed Jun 29 11:06:13 2016 New Revision: 302276 URL: https://svnweb.freebsd.org/changeset/base/302276 Log: MFC r301956, r301957, r301964, r301966, r301968, r301969, r302080, r302125 and r302171: Added multiple new LibUSB v1.0 API functions. Streams support is only available in FreeBSD 10+. Refer to the individual commits for more details. Added: stable/9/lib/libusb/libusb10_hotplug.c - copied unchanged from r302080, head/lib/libusb/libusb10_hotplug.c Modified: stable/9/lib/libusb/Makefile stable/9/lib/libusb/libusb.3 stable/9/lib/libusb/libusb.h stable/9/lib/libusb/libusb10.c stable/9/lib/libusb/libusb10.h stable/9/lib/libusb/libusb10_desc.c stable/9/lib/libusb/libusb10_io.c stable/9/lib/libusb/libusb20.c stable/9/lib/libusb/libusb20_int.h Directory Properties: stable/9/lib/ (props changed) stable/9/lib/libusb/ (props changed) Modified: stable/9/lib/libusb/Makefile ============================================================================== --- stable/9/lib/libusb/Makefile Wed Jun 29 10:58:36 2016 (r302275) +++ stable/9/lib/libusb/Makefile Wed Jun 29 11:06:13 2016 (r302276) @@ -31,6 +31,7 @@ SRCS+= libusb01.c INCS+= libusb.h SRCS+= libusb10.c SRCS+= libusb10_desc.c +SRCS+= libusb10_hotplug.c SRCS+= libusb10_io.c .if defined(COMPAT_32BIT) @@ -40,6 +41,7 @@ CFLAGS+= -DCOMPAT_32BIT .include # LibUSB v1.0 +MLINKS += libusb.3 libusb_get_version.3 MLINKS += libusb.3 libusb_init.3 MLINKS += libusb.3 libusb_exit.3 MLINKS += libusb.3 libusb_strerror.3 @@ -48,6 +50,7 @@ MLINKS += libusb.3 libusb_set_debug.3 MLINKS += libusb.3 libusb_get_device_list.3 MLINKS += libusb.3 libusb_free_device_list.3 MLINKS += libusb.3 libusb_get_bus_number.3 +MLINKS += libusb.3 libusb_get_port_number.3 MLINKS += libusb.3 libusb_get_device_address.3 MLINKS += libusb.3 libusb_get_device_speed.3 MLINKS += libusb.3 libusb_get_max_packet_size.3 @@ -72,6 +75,7 @@ MLINKS += libusb.3 libusb_get_driver_np. MLINKS += libusb.3 libusb_detach_kernel_driver.3 MLINKS += libusb.3 libusb_detach_kernel_driver_np.3 MLINKS += libusb.3 libusb_attach_kernel_driver.3 +MLINKS += libusb.3 libusb_set_auto_detach_kernel_driver.3 MLINKS += libusb.3 libusb_get_device_descriptor.3 MLINKS += libusb.3 libusb_get_active_config_descriptor.3 MLINKS += libusb.3 libusb_get_config_descriptor.3 @@ -81,10 +85,22 @@ MLINKS += libusb.3 libusb_get_string_des MLINKS += libusb.3 libusb_get_string_descriptor_ascii.3 MLINKS += libusb.3 libusb_parse_ss_endpoint_comp.3 MLINKS += libusb.3 libusb_free_ss_endpoint_comp.3 +MLINKS += libusb.3 libusb_get_ss_endpoint_companion_descriptor.3 +MLINKS += libusb.3 libusb_free_ss_endpoint_companion_descriptor.3 MLINKS += libusb.3 libusb_parse_bos_descriptor.3 MLINKS += libusb.3 libusb_free_bos_descriptor.3 +MLINKS += libusb.3 libusb_get_usb_2_0_extension_descriptor.3 +MLINKS += libusb.3 libusb_free_usb_2_0_extension_descriptor.3 +MLINKS += libusb.3 libusb_get_ss_usb_device_capability_descriptor.3 +MLINKS += libusb.3 libusb_free_ss_usb_device_capability_descriptor.3 +MLINKS += libusb.3 libusb_get_container_id_descriptor.3 +MLINKS += libusb.3 libusb_free_container_id_descriptor.3 +MLINKS += libusb.3 libusb_alloc_streams.3 +MLINKS += libusb.3 libusb_free_streams.3 MLINKS += libusb.3 libusb_alloc_transfer.3 MLINKS += libusb.3 libusb_free_transfer.3 +MLINKS += libusb.3 libusb_transfer_set_stream_id.3 +MLINKS += libusb.3 libusb_transfer_get_stream_id.3 MLINKS += libusb.3 libusb_submit_transfer.3 MLINKS += libusb.3 libusb_cancel_transfer.3 MLINKS += libusb.3 libusb_control_transfer.3 @@ -106,6 +122,8 @@ MLINKS += libusb.3 libusb_handle_events_ MLINKS += libusb.3 libusb_get_next_timeout.3 MLINKS += libusb.3 libusb_set_pollfd_notifiers.3 MLINKS += libusb.3 libusb_get_pollfds.3 +MLINKS += libusb.3 libusb_hotplug_register_callback.3 +MLINKS += libusb.3 libusb_hotplug_deregister_callback.3 # LibUSB v0.1 MLINKS += libusb.3 usb_open.3 Modified: stable/9/lib/libusb/libusb.3 ============================================================================== --- stable/9/lib/libusb/libusb.3 Wed Jun 29 10:58:36 2016 (r302275) +++ stable/9/lib/libusb/libusb.3 Wed Jun 29 11:06:13 2016 (r302276) @@ -26,7 +26,7 @@ .\" .\" $FreeBSD$ .\" -.Dd January 5, 2014 +.Dd June 23, 2016 .Dt LIBUSB 3 .Os .Sh NAME @@ -43,6 +43,10 @@ The library contains interfaces for directly managing a usb device. The current implementation supports v1.0 of the libusb API. .Sh LIBRARY INITIALISATION / DEINITIALISATION +.Ft "const struct libusb_version *" +.Fn libusb_get_version "void" +This function returns version information about LibUSB. +.Pp .Ft int .Fn libusb_init libusb_context **ctx This function initialises libusb. @@ -102,6 +106,12 @@ counter decremented once. Returns the number of the bus contained by the device .Fa dev . .Pp +.Ft uint8_t +.Fn libusb_get_port_number "libusb_device *dev" +Returns the port number which the device given by +.Fa dev +is attached to. +.Pp .Ft int .Fn libusb_get_port_numbers "libusb_device *dev" "uint8_t *buf" "uint8_t bufsize" Stores, in the buffer @@ -288,6 +298,18 @@ LIBUSB_ERROR_NO_DEVICE if the device has been disconnected, LIBUSB_ERROR_BUSY if the driver cannot be attached because the interface is claimed by a program or driver and a LIBUSB_ERROR code on failure. +.Pp +.Ft int +.Fn libusb_set_auto_detach_kernel_driver "libusb_device_handle *devh" "int enable" +This function enables automatic kernel interface driver detach when an +interface is claimed. +When the interface is restored the kernel driver is allowed to be re-attached. +If the +.Fa enable +argument is non-zero the feature is enabled. +Else disabled. +Returns 0 on success and a LIBUSB_ERROR code on +failure. .Sh USB DESCRIPTORS .Ft int .Fn libusb_get_device_descriptor "libusb_device *dev" "libusb_device_descriptor *desc" @@ -354,7 +376,31 @@ freed using the libusb_free_ss_endpoint_ .Pp .Ft void .Fn libusb_free_ss_endpoint_comp "libusb_ss_endpoint_companion_descriptor *ep_comp" -This function is NULL safe and frees a parsed USB 3.0 endpoint companion descriptor. +This function is NULL safe and frees a parsed USB 3.0 endpoint companion descriptor given by +.Fa ep_comp . +.Pp +.Ft int +.Fn libusb_get_ss_endpoint_companion_descriptor "struct libusb_context *ctx" "const struct libusb_endpoint_descriptor *endpoint" "struct libusb_ss_endpoint_companion_descriptor **ep_comp" +This function finds and parses the USB 3.0 endpoint companion descriptor given by +.Fa endpoint . +Returns zero on success and a LIBUSB_ERROR code on failure. +On success the parsed USB 3.0 endpoint companion descriptor must be +freed using the libusb_free_ss_endpoint_companion_descriptor function. +.Pp +.Ft void +.Fn libusb_free_ss_endpoint_companion_descriptor "struct libusb_ss_endpoint_companion_descriptor *ep_comp" +This function is NULL safe and frees a parsed USB 3.0 endpoint companion descriptor given by +.Fa ep_comp . +.Pp +.Ft int +.Fn libusb_get_bos_descriptor "libusb_device_handle *handle" "struct libusb_bos_descriptor **bos" +This function queries the USB device given by +.Fa handle +and stores a pointer to a parsed BOS descriptor into +.Fa bos . +Returns zero on success and a LIBUSB_ERROR code on failure. +On success the parsed BOS descriptor must be +freed using the libusb_free_bos_descriptor function. .Pp .Ft int .Fn libusb_parse_bos_descriptor "const void *buf" "int len" "libusb_bos_descriptor **bos" @@ -370,7 +416,53 @@ libusb_free_bos_descriptor function. .Pp .Ft void .Fn libusb_free_bos_descriptor "libusb_bos_descriptor *bos" -This function is NULL safe and frees a parsed BOS descriptor. +This function is NULL safe and frees a parsed BOS descriptor given by +.Fa bos . +.Pp +.Ft int +.Fn libusb_get_usb_2_0_extension_descriptor "struct libusb_context *ctx" "struct libusb_bos_dev_capability_descriptor *dev_cap" "struct libusb_usb_2_0_extension_descriptor **usb_2_0_extension" +This function parses the USB 2.0 extension descriptor from the descriptor given by +.Fa dev_cap +and stores a pointer to the parsed descriptor into +.Fa usb_2_0_extension . +Returns zero on success and a LIBUSB_ERROR code on failure. +On success the parsed USB 2.0 extension descriptor must be freed using the +libusb_free_usb_2_0_extension_descriptor function. +.Pp +.Ft void +.Fn libusb_free_usb_2_0_extension_descriptor "struct libusb_usb_2_0_extension_descriptor *usb_2_0_extension" +This function is NULL safe and frees a parsed USB 2.0 extension descriptor given by +.Fa usb_2_0_extension . +.Pp +.Ft int +.Fn libusb_get_ss_usb_device_capability_descriptor "struct libusb_context *ctx" "struct libusb_bos_dev_capability_descriptor *dev_cap" "struct libusb_ss_usb_device_capability_descriptor **ss_usb_device_capability" +This function parses the SuperSpeed device capability descriptor from the descriptor given by +.Fa dev_cap +and stores a pointer to the parsed descriptor into +.Fa ss_usb_device_capability . +Returns zero on success and a LIBUSB_ERROR code on failure. +On success the parsed SuperSpeed device capability descriptor must be freed using the +libusb_free_ss_usb_device_capability_descriptor function. +.Pp +.Ft void +.Fn libusb_free_ss_usb_device_capability_descriptor "struct libusb_ss_usb_device_capability_descriptor *ss_usb_device_capability" +This function is NULL safe and frees a parsed SuperSpeed device capability descriptor given by +.Fa ss_usb_device_capability . +.Pp +.Ft int +.Fn libusb_get_container_id_descriptor "struct libusb_context *ctx" "struct libusb_bos_dev_capability_descriptor *dev_cap" "struct libusb_container_id_descriptor **container_id" +This function parses the container ID descriptor from the descriptor given by +.Fa dev_cap +and stores a pointer to the parsed descriptor into +.Fa container_id . +Returns zero on success and a LIBUSB_ERROR code on failure. +On success the parsed container ID descriptor must be freed using the +libusb_free_container_id_descriptor function. +.Pp +.Ft void +.Fn libusb_free_container_id_descriptor "struct libusb_container_id_descriptor *container_id" +This function is NULL safe and frees a parsed container ID descriptor given by +.Fa container_id . .Sh USB ASYNCHRONOUS I/O .Ft struct libusb_transfer * .Fn libusb_alloc_transfer "int iso_packets" @@ -429,6 +521,29 @@ if the transfer timed out, LIBUSB_ERROR_ supported, LIBUSB_ERROR_OVERFLOW if the device offered more data, LIBUSB_ERROR_NO_DEVICE if the device has been disconnected and a LIBUSB_ERROR code on other failure. +.Sh USB STREAMS SUPPORT +.Ft int +.Fn libusb_alloc_streams "libusb_device_handle *dev" "uint32_t num_streams" "unsigned char *endpoints" "int num_endpoints" +This function verifies that the given number of streams using the +given number of endpoints is allowed and allocates the resources +needed to use so-called USB streams. +Currently only a single stream per endpoint is supported to simplify +the internals of LibUSB. +This function returns 0 on success or a LIBUSB_ERROR code on failure. +.Pp +.Ft int +.Fn libusb_free_streams "libusb_device_handle *dev" "unsigned char *endpoints" "int num_endpoints" +This function release resources needed for streams usage. +Returns 0 on success or a LIBUSB_ERROR code on failure. +.Pp +.Ft void +.Fn libusb_transfer_set_stream_id "struct libusb_transfer *transfer" "uint32_t stream_id" +This function sets the stream ID for the given USB transfer. +.Pp +.Ft uint32_t +.Fn libusb_transfer_get_stream_id "struct libusb_transfer *transfer" +This function returns the stream ID for the given USB transfer. +If no stream ID is used a value of zero is returned. .Sh USB EVENTS .Ft int .Fn libusb_try_lock_events "libusb_context *ctx" @@ -550,6 +665,47 @@ that libusb uses as an event source. Retrive a list of file descriptors that should be polled by your main loop as libusb event sources. Returns a NULL-terminated list on success or NULL on failure. +.Pp +.Ft int +.Fn libusb_hotplug_register_callback "libusb_context *ctx" "libusb_hotplug_event events" "libusb_hotplug_flag flags" "int vendor_id" "int product_id" "int dev_class" "libusb_hotplug_callback_fn cb_fn" "void *user_data" "libusb_hotplug_callback_handle *handle" +This function registers a hotplug filter. +The +.Fa events +argument select which events makes the hotplug filter trigger. +Available event values are LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED and LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT. +One or more events must be specified. +The +.Fa vendor_id , +.Fa product_id +and +.Fa dev_class +arguments can be set to LIBUSB_HOTPLUG_MATCH_ANY to match any value in the USB device descriptor. +Else the specified value is used for matching. +If the +.Fa flags +argument is set to LIBUSB_HOTPLUG_ENUMERATE, all currently attached and matching USB devices will be passed to the hotplug filter, given by the +.Fa cb_fn +argument. +Else the +.Fa flags +argument should be set to LIBUSB_HOTPLUG_NO_FLAGS. +This function returns 0 upon success or a LIBUSB_ERROR code on failure. +.Pp +.Ft int +.Fn libusb_hotplug_callback_fn "libusb_context *ctx" "libusb_device *device" "libusb_hotplug_event event" "void *user_data" +The hotplug filter function. +If this function returns non-zero, the filter is removed. +Else the filter is kept and can receive more events. +The +.Fa user_data +argument is the same as given when the filter was registered. +The +.Fa event +argument can be either of LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED or LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT. +.Pp +.Ft void +.Fn libusb_hotplug_deregister_callback "libusb_context *ctx" "libusb_hotplug_callback_handle handle" +This function unregisters a hotplug filter. .Sh LIBUSB VERSION 0.1 COMPATIBILITY The library is also compliant with LibUSB version 0.1.12. .Pp Modified: stable/9/lib/libusb/libusb.h ============================================================================== --- stable/9/lib/libusb/libusb.h Wed Jun 29 10:58:36 2016 (r302275) +++ stable/9/lib/libusb/libusb.h Wed Jun 29 11:06:13 2016 (r302276) @@ -30,6 +30,8 @@ #include #include +#define LIBUSB_API_VERSION 0x01000102 + #define LIBUSB_CALL #ifdef __cplusplus @@ -96,6 +98,10 @@ enum libusb_device_capability_type { #define LIBUSB_USB_2_0_EXTENSION_DEVICE_CAPABILITY_SIZE 7 #define LIBUSB_SS_USB_DEVICE_CAPABILITY_SIZE 10 +#define LIBUSB_BT_USB_2_0_EXTENSION_SIZE 7 +#define LIBUSB_BT_SS_USB_DEVICE_CAPABILITY_SIZE 10 +#define LIBUSB_BT_CONTAINER_ID_SIZE 20 + #define LIBUSB_ENDPOINT_ADDRESS_MASK 0x0f #define LIBUSB_ENDPOINT_DIR_MASK 0x80 @@ -160,6 +166,13 @@ enum libusb_iso_usage_type { LIBUSB_ISO_USAGE_TYPE_IMPLICIT = 2, }; +enum libusb_bos_type { + LIBUSB_BT_WIRELESS_USB_DEVICE_CAPABILITY = 1, + LIBUSB_BT_USB_2_0_EXTENSION = 2, + LIBUSB_BT_SS_USB_DEVICE_CAPABILITY = 3, + LIBUSB_BT_CONTAINER_ID = 4, +}; + enum libusb_error { LIBUSB_SUCCESS = 0, LIBUSB_ERROR_IO = -1, @@ -207,24 +220,47 @@ enum libusb_debug_level { LIBUSB_DEBUG_TRANSFER=2, }; +#define LIBUSB_HOTPLUG_MATCH_ANY -1 + +typedef enum { + LIBUSB_HOTPLUG_NO_FLAGS = 0, + LIBUSB_HOTPLUG_ENUMERATE = 1 << 0, +} libusb_hotplug_flag; + +typedef enum { + LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED = 1, + LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT = 2, +} libusb_hotplug_event; + /* libusb structures */ struct libusb_context; struct libusb_device; struct libusb_transfer; struct libusb_device_handle; +struct libusb_hotplug_callback_handle_struct; struct libusb_pollfd { int fd; short events; }; +struct libusb_version { + const uint16_t major; + const uint16_t minor; + const uint16_t micro; + const uint16_t nano; + const char *rc; + const char *describe; +}; + typedef struct libusb_context libusb_context; typedef struct libusb_device libusb_device; typedef struct libusb_device_handle libusb_device_handle; typedef struct libusb_pollfd libusb_pollfd; typedef void (*libusb_pollfd_added_cb) (int fd, short events, void *user_data); typedef void (*libusb_pollfd_removed_cb) (int fd, void *user_data); +typedef struct libusb_hotplug_callback_handle_struct *libusb_hotplug_callback_handle; typedef struct libusb_device_descriptor { uint8_t bLength; @@ -322,6 +358,13 @@ typedef struct libusb_ss_usb_device_capa uint16_t wU2DevExitLat; } libusb_ss_usb_device_capability_descriptor __aligned(sizeof(void *)); +typedef struct libusb_bos_dev_capability_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDevCapabilityType; + uint8_t dev_capability_data[0]; +} libusb_bos_dev_capability_descriptor __aligned(sizeof(void *)); + typedef struct libusb_bos_descriptor { uint8_t bLength; uint8_t bDescriptorType; @@ -331,6 +374,21 @@ typedef struct libusb_bos_descriptor { struct libusb_ss_usb_device_capability_descriptor *ss_usb_cap; } libusb_bos_descriptor __aligned(sizeof(void *)); +typedef struct libusb_usb_2_0_extension_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDevCapabilityType; + uint32_t bmAttributes; +} libusb_usb_2_0_extension_descriptor __aligned(sizeof(void *)); + +typedef struct libusb_container_id_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDevCapabilityType; + uint8_t bReserved; + uint8_t ContainerID[16]; +} libusb_container_id_descriptor __aligned(sizeof(void *)); + typedef struct libusb_control_setup { uint8_t bmRequestType; uint8_t bRequest; @@ -369,6 +427,7 @@ typedef struct libusb_transfer { /* Library initialisation */ void libusb_set_debug(libusb_context * ctx, int level); +const struct libusb_version *libusb_get_version(void); const char *libusb_strerror(int code); const char *libusb_error_name(int code); int libusb_init(libusb_context ** context); @@ -379,6 +438,7 @@ void libusb_exit(struct libusb_context * ssize_t libusb_get_device_list(libusb_context * ctx, libusb_device *** list); void libusb_free_device_list(libusb_device ** list, int unref_devices); uint8_t libusb_get_bus_number(libusb_device * dev); +uint8_t libusb_get_port_number(libusb_device * dev); int libusb_get_port_numbers(libusb_device *dev, uint8_t *buf, uint8_t bufsize); int libusb_get_port_path(libusb_context *ctx, libusb_device *dev, uint8_t *buf, uint8_t bufsize); uint8_t libusb_get_device_address(libusb_device * dev); @@ -404,6 +464,7 @@ int libusb_get_driver(libusb_device_hand int libusb_detach_kernel_driver_np(libusb_device_handle * devh, int interface); int libusb_detach_kernel_driver(libusb_device_handle * devh, int interface); int libusb_attach_kernel_driver(libusb_device_handle * devh, int interface); +int libusb_set_auto_detach_kernel_driver(libusb_device_handle *dev, int enable); int libusb_set_interface_alt_setting(libusb_device_handle * devh, int interface_number, int alternate_setting); /* USB Descriptors */ @@ -413,6 +474,8 @@ int libusb_get_active_config_descriptor( int libusb_get_config_descriptor(libusb_device * dev, uint8_t config_index, struct libusb_config_descriptor **config); int libusb_get_config_descriptor_by_value(libusb_device * dev, uint8_t bConfigurationValue, struct libusb_config_descriptor **config); void libusb_free_config_descriptor(struct libusb_config_descriptor *config); +int libusb_get_ss_endpoint_companion_descriptor(struct libusb_context *ctx, const struct libusb_endpoint_descriptor *endpoint, struct libusb_ss_endpoint_companion_descriptor **ep_comp); +void libusb_free_ss_endpoint_companion_descriptor(struct libusb_ss_endpoint_companion_descriptor *ep_comp); int libusb_get_string_descriptor(libusb_device_handle * devh, uint8_t desc_index, uint16_t langid, unsigned char *data, int length); int libusb_get_string_descriptor_ascii(libusb_device_handle * devh, uint8_t desc_index, uint8_t *data, int length); int libusb_get_descriptor(libusb_device_handle * devh, uint8_t desc_type, uint8_t desc_index, uint8_t *data, int length); @@ -420,6 +483,13 @@ int libusb_parse_ss_endpoint_comp(const void libusb_free_ss_endpoint_comp(struct libusb_ss_endpoint_companion_descriptor *ep_comp); int libusb_parse_bos_descriptor(const void *buf, int len, struct libusb_bos_descriptor **bos); void libusb_free_bos_descriptor(struct libusb_bos_descriptor *bos); +int libusb_get_bos_descriptor(libusb_device_handle *handle, struct libusb_bos_descriptor **bos); +int libusb_get_usb_2_0_extension_descriptor(struct libusb_context *ctx, struct libusb_bos_dev_capability_descriptor *dev_cap, struct libusb_usb_2_0_extension_descriptor **usb_2_0_extension); +void libusb_free_usb_2_0_extension_descriptor(struct libusb_usb_2_0_extension_descriptor *usb_2_0_extension); +int libusb_get_ss_usb_device_capability_descriptor(struct libusb_context *ctx, struct libusb_bos_dev_capability_descriptor *dev_cap, struct libusb_ss_usb_device_capability_descriptor **ss_usb_device_capability); +void libusb_free_ss_usb_device_capability_descriptor(struct libusb_ss_usb_device_capability_descriptor *ss_usb_device_capability); +int libusb_get_container_id_descriptor(struct libusb_context *ctx, struct libusb_bos_dev_capability_descriptor *dev_cap, struct libusb_container_id_descriptor **container_id); +void libusb_free_container_id_descriptor(struct libusb_container_id_descriptor *container_id); /* Asynchronous device I/O */ @@ -468,6 +538,21 @@ int libusb_interrupt_transfer(libusb_dev uint16_t libusb_cpu_to_le16(uint16_t x); uint16_t libusb_le16_to_cpu(uint16_t x); +/* Hotplug support */ + +typedef int (*libusb_hotplug_callback_fn)(libusb_context *ctx, + libusb_device *device, libusb_hotplug_event event, void *user_data); + +int libusb_hotplug_register_callback(libusb_context *ctx, libusb_hotplug_event events, libusb_hotplug_flag flags, int vendor_id, int product_id, int dev_class, libusb_hotplug_callback_fn cb_fn, void *user_data, libusb_hotplug_callback_handle *handle); +void libusb_hotplug_deregister_callback(libusb_context *ctx, libusb_hotplug_callback_handle handle); + +/* Streams support */ + +int libusb_alloc_streams(libusb_device_handle *dev, uint32_t num_streams, unsigned char *endpoints, int num_endpoints); +int libusb_free_streams(libusb_device_handle *dev, unsigned char *endpoints, int num_endpoints); +void libusb_transfer_set_stream_id(struct libusb_transfer *transfer, uint32_t stream_id); +uint32_t libusb_transfer_get_stream_id(struct libusb_transfer *transfer); + #if 0 { /* indent fix */ #endif Modified: stable/9/lib/libusb/libusb10.c ============================================================================== --- stable/9/lib/libusb/libusb10.c Wed Jun 29 10:58:36 2016 (r302275) +++ stable/9/lib/libusb/libusb10.c Wed Jun 29 11:06:13 2016 (r302276) @@ -63,6 +63,22 @@ static void libusb10_submit_transfer_sub /* Library initialisation / deinitialisation */ +static const struct libusb_version libusb_version = { + .major = 1, + .minor = 0, + .micro = 0, + .nano = 2016, + .rc = "", + .describe = "http://www.freebsd.org" +}; + +const struct libusb_version * +libusb_get_version(void) +{ + + return (&libusb_version); +} + void libusb_set_debug(libusb_context *ctx, int level) { @@ -112,24 +128,34 @@ libusb_init(libusb_context **context) } TAILQ_INIT(&ctx->pollfds); TAILQ_INIT(&ctx->tr_done); + TAILQ_INIT(&ctx->hotplug_cbh); + TAILQ_INIT(&ctx->hotplug_devs); if (pthread_mutex_init(&ctx->ctx_lock, NULL) != 0) { free(ctx); return (LIBUSB_ERROR_NO_MEM); } + if (pthread_mutex_init(&ctx->hotplug_lock, NULL) != 0) { + pthread_mutex_destroy(&ctx->ctx_lock); + free(ctx); + return (LIBUSB_ERROR_NO_MEM); + } if (pthread_condattr_init(&attr) != 0) { pthread_mutex_destroy(&ctx->ctx_lock); + pthread_mutex_destroy(&ctx->hotplug_lock); free(ctx); return (LIBUSB_ERROR_NO_MEM); } if (pthread_condattr_setclock(&attr, CLOCK_MONOTONIC) != 0) { pthread_mutex_destroy(&ctx->ctx_lock); + pthread_mutex_destroy(&ctx->hotplug_lock); pthread_condattr_destroy(&attr); free(ctx); return (LIBUSB_ERROR_OTHER); } if (pthread_cond_init(&ctx->ctx_cond, &attr) != 0) { pthread_mutex_destroy(&ctx->ctx_lock); + pthread_mutex_destroy(&ctx->hotplug_lock); pthread_condattr_destroy(&attr); free(ctx); return (LIBUSB_ERROR_NO_MEM); @@ -137,10 +163,12 @@ libusb_init(libusb_context **context) pthread_condattr_destroy(&attr); ctx->ctx_handler = NO_THREAD; + ctx->hotplug_handler = NO_THREAD; ret = pipe(ctx->ctrl_pipe); if (ret < 0) { pthread_mutex_destroy(&ctx->ctx_lock); + pthread_mutex_destroy(&ctx->hotplug_lock); pthread_cond_destroy(&ctx->ctx_cond); free(ctx); return (LIBUSB_ERROR_OTHER); @@ -173,12 +201,27 @@ libusb_exit(libusb_context *ctx) if (ctx == NULL) return; + /* stop hotplug thread, if any */ + + if (ctx->hotplug_handler != NO_THREAD) { + pthread_t td; + void *ptr; + + HOTPLUG_LOCK(ctx); + td = ctx->hotplug_handler; + ctx->hotplug_handler = NO_THREAD; + HOTPLUG_UNLOCK(ctx); + + pthread_join(td, &ptr); + } + /* XXX cleanup devices */ libusb10_remove_pollfd(ctx, &ctx->ctx_poll); close(ctx->ctrl_pipe[0]); close(ctx->ctrl_pipe[1]); pthread_mutex_destroy(&ctx->ctx_lock); + pthread_mutex_destroy(&ctx->hotplug_lock); pthread_cond_destroy(&ctx->ctx_cond); pthread_mutex_lock(&default_context_lock); @@ -286,6 +329,14 @@ libusb_get_bus_number(libusb_device *dev return (libusb20_dev_get_bus_number(dev->os_priv)); } +uint8_t +libusb_get_port_number(libusb_device *dev) +{ + if (dev == NULL) + return (0); /* should not happen */ + return (libusb20_dev_get_parent_port(dev->os_priv)); +} + int libusb_get_port_numbers(libusb_device *dev, uint8_t *buf, uint8_t bufsize) { @@ -607,6 +658,7 @@ int libusb_claim_interface(struct libusb20_device *pdev, int interface_number) { libusb_device *dev; + int err = 0; dev = libusb_get_device(pdev); if (dev == NULL) @@ -615,11 +667,17 @@ libusb_claim_interface(struct libusb20_d if (interface_number < 0 || interface_number > 31) return (LIBUSB_ERROR_INVALID_PARAM); + if (pdev->auto_detach != 0) { + err = libusb_detach_kernel_driver(pdev, interface_number); + if (err != 0) + goto done; + } + CTX_LOCK(dev->ctx); dev->claimed_interfaces |= (1 << interface_number); CTX_UNLOCK(dev->ctx); - - return (0); +done: + return (err); } int @@ -635,13 +693,19 @@ libusb_release_interface(struct libusb20 if (interface_number < 0 || interface_number > 31) return (LIBUSB_ERROR_INVALID_PARAM); + if (pdev->auto_detach != 0) { + err = libusb_attach_kernel_driver(pdev, interface_number); + if (err != 0) + goto done; + } + CTX_LOCK(dev->ctx); if (!(dev->claimed_interfaces & (1 << interface_number))) err = LIBUSB_ERROR_NOT_FOUND; - - if (!err) + else dev->claimed_interfaces &= ~(1 << interface_number); CTX_UNLOCK(dev->ctx); +done: return (err); } @@ -843,6 +907,13 @@ libusb_attach_kernel_driver(struct libus return (0); } +int +libusb_set_auto_detach_kernel_driver(libusb_device_handle *dev, int enable) +{ + dev->auto_detach = (enable ? 1 : 0); + return (0); +} + /* Asynchronous device I/O */ struct libusb_transfer * Modified: stable/9/lib/libusb/libusb10.h ============================================================================== --- stable/9/lib/libusb/libusb10.h Wed Jun 29 10:58:36 2016 (r302275) +++ stable/9/lib/libusb/libusb10.h Wed Jun 29 11:06:13 2016 (r302276) @@ -34,6 +34,8 @@ #define CTX_LOCK(ctx) pthread_mutex_lock(&(ctx)->ctx_lock) #define CTX_TRYLOCK(ctx) pthread_mutex_trylock(&(ctx)->ctx_lock) #define CTX_UNLOCK(ctx) pthread_mutex_unlock(&(ctx)->ctx_lock) +#define HOTPLUG_LOCK(ctx) pthread_mutex_lock(&(ctx)->hotplug_lock) +#define HOTPLUG_UNLOCK(ctx) pthread_mutex_unlock(&(ctx)->hotplug_lock) #define DPRINTF(ctx, dbg, format, args...) do { \ if ((ctx)->debug == dbg) { \ @@ -65,11 +67,22 @@ struct libusb_super_transfer { uint8_t *curr_data; uint32_t rem_len; uint32_t last_len; + uint32_t stream_id; uint8_t state; #define LIBUSB_SUPER_XFER_ST_NONE 0 #define LIBUSB_SUPER_XFER_ST_PEND 1 }; +struct libusb_hotplug_callback_handle_struct { + TAILQ_ENTRY(libusb_hotplug_callback_handle_struct) entry; + int events; + int vendor; + int product; + int devclass; + libusb_hotplug_callback_fn fn; + void *user_data; +}; + struct libusb_context { int debug; int debug_fixed; @@ -78,12 +91,16 @@ struct libusb_context { int tr_done_gen; pthread_mutex_t ctx_lock; + pthread_mutex_t hotplug_lock; pthread_cond_t ctx_cond; + pthread_t hotplug_handler; pthread_t ctx_handler; #define NO_THREAD ((pthread_t)-1) TAILQ_HEAD(, libusb_super_pollfd) pollfds; TAILQ_HEAD(, libusb_super_transfer) tr_done; + TAILQ_HEAD(, libusb_hotplug_callback_handle_struct) hotplug_cbh; + TAILQ_HEAD(, libusb_device) hotplug_devs; struct libusb_super_pollfd ctx_poll; @@ -101,6 +118,8 @@ struct libusb_device { struct libusb_context *ctx; + TAILQ_ENTRY(libusb_device) hotplug_entry; + TAILQ_HEAD(, libusb_super_transfer) tr_head; struct libusb20_device *os_priv; Modified: stable/9/lib/libusb/libusb10_desc.c ============================================================================== --- stable/9/lib/libusb/libusb10_desc.c Wed Jun 29 10:58:36 2016 (r302275) +++ stable/9/lib/libusb/libusb10_desc.c Wed Jun 29 11:06:13 2016 (r302276) @@ -405,6 +405,23 @@ libusb_free_ss_endpoint_comp(struct libu } int +libusb_get_ss_endpoint_companion_descriptor(struct libusb_context *ctx, + const struct libusb_endpoint_descriptor *endpoint, + struct libusb_ss_endpoint_companion_descriptor **ep_comp) +{ + if (endpoint == NULL) + return (LIBUSB_ERROR_INVALID_PARAM); + return (libusb_parse_ss_endpoint_comp(endpoint->extra, endpoint->extra_length, ep_comp)); +} + +void +libusb_free_ss_endpoint_companion_descriptor(struct libusb_ss_endpoint_companion_descriptor *ep_comp) +{ + + libusb_free_ss_endpoint_comp(ep_comp); +} + +int libusb_parse_bos_descriptor(const void *buf, int len, struct libusb_bos_descriptor **bos) { @@ -515,3 +532,154 @@ libusb_free_bos_descriptor(struct libusb free(bos); } + +int +libusb_get_bos_descriptor(libusb_device_handle *handle, + struct libusb_bos_descriptor **bos) +{ + uint8_t bos_header[LIBUSB_DT_BOS_SIZE] = {0}; + uint16_t wTotalLength; + uint8_t *bos_data; + int err; + + err = libusb_get_descriptor(handle, LIBUSB_DT_BOS, 0, + bos_header, sizeof(bos_header)); + if (err < 0) + return (err); + + wTotalLength = bos_header[2] | (bos_header[3] << 8); + if (wTotalLength < LIBUSB_DT_BOS_SIZE) + return (LIBUSB_ERROR_INVALID_PARAM); + + bos_data = calloc(wTotalLength, 1); + if (bos_data == NULL) + return (LIBUSB_ERROR_NO_MEM); + + err = libusb_get_descriptor(handle, LIBUSB_DT_BOS, 0, + bos_data, wTotalLength); + if (err < 0) + goto done; + + /* avoid descriptor length mismatches */ + bos_data[2] = (wTotalLength & 0xFF); + bos_data[3] = (wTotalLength >> 8); + + err = libusb_parse_bos_descriptor(bos_data, wTotalLength, bos); +done: + free(bos_data); + return (err); +} + +int +libusb_get_usb_2_0_extension_descriptor(struct libusb_context *ctx, + struct libusb_bos_dev_capability_descriptor *dev_cap, + struct libusb_usb_2_0_extension_descriptor **usb_2_0_extension) +{ + struct libusb_usb_2_0_extension_descriptor *desc; + + if (dev_cap == NULL || usb_2_0_extension == NULL || + dev_cap->bDevCapabilityType != LIBUSB_BT_USB_2_0_EXTENSION) + return (LIBUSB_ERROR_INVALID_PARAM); + if (dev_cap->bLength < LIBUSB_BT_USB_2_0_EXTENSION_SIZE) + return (LIBUSB_ERROR_IO); + + desc = malloc(sizeof(*desc)); + if (desc == NULL) + return (LIBUSB_ERROR_NO_MEM); + + desc->bLength = LIBUSB_BT_USB_2_0_EXTENSION_SIZE; + desc->bDescriptorType = dev_cap->bDescriptorType; + desc->bDevCapabilityType = dev_cap->bDevCapabilityType; + desc->bmAttributes = + (dev_cap->dev_capability_data[0]) | + (dev_cap->dev_capability_data[1] << 8) | + (dev_cap->dev_capability_data[2] << 16) | + (dev_cap->dev_capability_data[3] << 24); + + *usb_2_0_extension = desc; + return (0); +} + +void +libusb_free_usb_2_0_extension_descriptor( + struct libusb_usb_2_0_extension_descriptor *usb_2_0_extension) +{ + + free(usb_2_0_extension); +} + +int +libusb_get_ss_usb_device_capability_descriptor(struct libusb_context *ctx, + struct libusb_bos_dev_capability_descriptor *dev_cap, + struct libusb_ss_usb_device_capability_descriptor **ss_usb_device_capability) +{ + struct libusb_ss_usb_device_capability_descriptor *desc; + + if (dev_cap == NULL || ss_usb_device_capability == NULL || + dev_cap->bDevCapabilityType != LIBUSB_BT_SS_USB_DEVICE_CAPABILITY) + return (LIBUSB_ERROR_INVALID_PARAM); + if (dev_cap->bLength < LIBUSB_BT_SS_USB_DEVICE_CAPABILITY_SIZE) + return (LIBUSB_ERROR_IO); + + desc = malloc(sizeof(*desc)); + if (desc == NULL) + return (LIBUSB_ERROR_NO_MEM); + + desc->bLength = LIBUSB_BT_SS_USB_DEVICE_CAPABILITY_SIZE; + desc->bDescriptorType = dev_cap->bDescriptorType; + desc->bDevCapabilityType = dev_cap->bDevCapabilityType; + desc->bmAttributes = dev_cap->dev_capability_data[0]; + desc->wSpeedSupported = dev_cap->dev_capability_data[1] | + (dev_cap->dev_capability_data[2] << 8); + desc->bFunctionalitySupport = dev_cap->dev_capability_data[3]; + desc->bU1DevExitLat = dev_cap->dev_capability_data[4]; + desc->wU2DevExitLat = dev_cap->dev_capability_data[5] | + (dev_cap->dev_capability_data[6] << 8); + + *ss_usb_device_capability = desc; + return (0); +} + +void +libusb_free_ss_usb_device_capability_descriptor( + struct libusb_ss_usb_device_capability_descriptor *ss_usb_device_capability) +{ + + free(ss_usb_device_capability); +} + +int +libusb_get_container_id_descriptor(struct libusb_context *ctx, + struct libusb_bos_dev_capability_descriptor *dev_cap, + struct libusb_container_id_descriptor **container_id) +{ + struct libusb_container_id_descriptor *desc; + + if (dev_cap == NULL || container_id == NULL || + dev_cap->bDevCapabilityType != LIBUSB_BT_CONTAINER_ID) + return (LIBUSB_ERROR_INVALID_PARAM); + if (dev_cap->bLength < LIBUSB_BT_CONTAINER_ID_SIZE) + return (LIBUSB_ERROR_IO); + + desc = malloc(sizeof(*desc)); + if (desc == NULL) + return (LIBUSB_ERROR_NO_MEM); + + desc->bLength = LIBUSB_BT_CONTAINER_ID_SIZE; + desc->bDescriptorType = dev_cap->bDescriptorType; + desc->bDevCapabilityType = dev_cap->bDevCapabilityType; + desc->bReserved = dev_cap->dev_capability_data[0]; + memcpy(desc->ContainerID, dev_cap->dev_capability_data + 1, + sizeof(desc->ContainerID)); + + *container_id = desc; + return (0); +} + +void +libusb_free_container_id_descriptor( + struct libusb_container_id_descriptor *container_id) +{ + + free(container_id); +} Copied: stable/9/lib/libusb/libusb10_hotplug.c (from r302080, head/lib/libusb/libusb10_hotplug.c) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ stable/9/lib/libusb/libusb10_hotplug.c Wed Jun 29 11:06:13 2016 (r302276, copy of r302080, head/lib/libusb/libusb10_hotplug.c) @@ -0,0 +1,237 @@ +/* $FreeBSD$ */ +/*- + * Copyright (c) 2016 Hans Petter Selasky. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifdef LIBUSB_GLOBAL_INCLUDE_FILE +#include LIBUSB_GLOBAL_INCLUDE_FILE +#else +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#endif + +#define libusb_device_handle libusb20_device + +#include "libusb20.h" +#include "libusb20_desc.h" +#include "libusb20_int.h" +#include "libusb.h" +#include "libusb10.h" + +static int +libusb_hotplug_equal(libusb_device *_adev, libusb_device *_bdev) +{ + struct libusb20_device *adev = _adev->os_priv; + struct libusb20_device *bdev = _bdev->os_priv; + + if (adev->bus_number != bdev->bus_number) + return (0); + if (adev->device_address != bdev->device_address) + return (0); + if (memcmp(&adev->ddesc, &bdev->ddesc, sizeof(adev->ddesc))) + return (0); + if (memcmp(&adev->session_data, &bdev->session_data, sizeof(adev->session_data))) + return (0); + return (1); +} + +static int +libusb_hotplug_filter(libusb_context *ctx, libusb_hotplug_callback_handle pcbh, + libusb_device *dev, libusb_hotplug_event event) +{ + if (!(pcbh->events & event)) + return (0); + if (pcbh->vendor != LIBUSB_HOTPLUG_MATCH_ANY && + pcbh->vendor != libusb20_dev_get_device_desc(dev->os_priv)->idVendor) + return (0); + if (pcbh->product != LIBUSB_HOTPLUG_MATCH_ANY && + pcbh->product != libusb20_dev_get_device_desc(dev->os_priv)->idProduct) + return (0); + if (pcbh->devclass != LIBUSB_HOTPLUG_MATCH_ANY && + pcbh->devclass != libusb20_dev_get_device_desc(dev->os_priv)->bDeviceClass) + return (0); + return (pcbh->fn(ctx, dev, event, pcbh->user_data)); +} + +static void * +libusb_hotplug_scan(void *arg) +{ + TAILQ_HEAD(, libusb_device) hotplug_devs; + libusb_hotplug_callback_handle acbh; + libusb_hotplug_callback_handle bcbh; + libusb_context *ctx = arg; + libusb_device **ppdev; + libusb_device *temp; + libusb_device *adev; + libusb_device *bdev; + unsigned do_loop = 1; + ssize_t count; + ssize_t x; *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***