mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-28 11:57:28 +00:00
src/sys/dev/usb2/controller/uss820dci_pccard.c
src/sys/dev/usb2/core/usbdevs src/sys/dev/usb2/include/urio2_ioctl.h src/sys/dev/usb2/storage/ustorage2_fs.h These files are not used any more. src/usr.sbin/Makefile src/etc/mtree/BSD.include.dist src/include/Makefile src/lib/Makefile src/share/man/man7/hier.7 src/share/mk/bsd.libnames.mk src/etc/mtree/BSD.include.dist Make "usbconfig" and "libusb20" a part of the default build. src/sys/dev/usb/rio500_usb.h src/sys/dev/usb2/storage/urio2.c Use common include file. src/sys/dev/usb2/bluetooth/ng_ubt2.c Make USB bluetooth depend on "ng_hci" module. src/sys/dev/usb2/controller/ehci2.c src/sys/dev/usb2/controller/ehci2.h Patches for Marvell EHCI. src/sys/dev/usb2/core/usb2_busdma.c Bugfix for 64-bit platforms. Need to unload the previously loaded DMA map and some cleanup regarding some corner cases. src/sys/dev/usb2/core/usb2_core.h src/sys/dev/usb2/core/usb2_dev.c src/sys/dev/usb2/core/usb2_dev.h Bugfix for libusb filesystem interface. New feature: Add support for filtering device data at the expense of the userland process. Add some more comments. Some minor code styling. Remove unused function, usb2_fifo_get_data_next(). Fix an issue about "fifo_index" being used instead of "ep_index". src/sys/dev/usb2/core/usb2_device.c src/sys/dev/usb2/core/usb2_generic.c Bugfix for Linux USB compat layer. Do not free non-generic FIFOs when doing an alternate setting. Cleanup USB IOCTL and USB reference handling. Fix a corner case where USB-FS was left initialised after setting a new configuration or alternate setting. src/sys/dev/usb2/core/usb2_hub.c Improvement: Check all USB HUB ports by default at least one time. src/sys/dev/usb2/core/usb2_request.c Bugfix: Make sure destination ASCII string is properly zero terminated in all cases. Improvement: Skip invalid characters instead of replacing with a dot. src/sys/dev/usb2/core/usb2_util.c src/sys/dev/usb2/image/uscanner2.c Spelling. src/sys/dev/usb2/include/Makefile Share "usbdevs" with the old USB stack. src/sys/dev/usb2/include/usb2_devid.h src/sys/dev/usb2/include/usb2_devtable.h Regenerate files. Alfred: Please fix the RCS tag at the top. src/sys/dev/usb2/include/usb2_ioctl.h Fix compilation of "kdump". src/sys/dev/usb2/serial/ubsa2.c src/sys/dev/usb2/serial/ugensa2.c Remove device ID's which will end up in a new 3G driver. src/sys/dev/usb2/sound/uaudio2.c Correct a debug printout. src/sys/dev/usb2/storage/umass2.c Sync with old USB stack. src/lib/libusb20/libusb20.3 Add more documentation. src/lib/libusb20/libusb20.c Various bugfixes and improvements. src/usr.sbin/usbconfig/dump.c src/usr.sbin/usbconfig/usbconfig.c New commands for dumping strings and doing custom USB requests from the command line. Remove keyword requirements from generated files: "head/sys/dev/usb2/include/usb2_devid.h" "head/sys/dev/usb2/include/usb2_devtable.h"
This commit is contained in:
parent
202f306c24
commit
6f0e1ffd07
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=185087
@ -120,6 +120,10 @@
|
||||
..
|
||||
usb
|
||||
..
|
||||
usb2
|
||||
include
|
||||
..
|
||||
..
|
||||
utopia
|
||||
..
|
||||
vkbd
|
||||
|
@ -54,7 +54,7 @@ LSUBDIRS= cam/scsi \
|
||||
security/mac_mls security/mac_partition \
|
||||
ufs/ffs ufs/ufs
|
||||
|
||||
LSUBSUBDIRS= dev/mpt/mpilib
|
||||
LSUBSUBDIRS= dev/mpt/mpilib dev/usb2/include
|
||||
|
||||
.if ${MACHINE_ARCH} == "powerpc"
|
||||
_dev_powermac_nvram= dev/powermac_nvram
|
||||
|
@ -38,7 +38,8 @@ SUBDIR= ${_csu} libc libbsm libcom_err libcrypt libelf libkvm msun libmd \
|
||||
${_libpmc} libproc librt ${_libsdp} ${_libsm} ${_libsmb} \
|
||||
${_libsmdb} \
|
||||
${_libsmutil} libstand ${_libtelnet} ${_libthr} libthread_db libufs \
|
||||
libugidfw ${_libusbhid} ${_libvgl} libwrap liby libz ${_bind}
|
||||
libugidfw ${_libusbhid} ${_libusb20} ${_libvgl} libwrap liby libz \
|
||||
${_bind}
|
||||
|
||||
.if exists(${.CURDIR}/csu/${MACHINE_ARCH}-elf)
|
||||
_csu=csu/${MACHINE_ARCH}-elf
|
||||
@ -136,6 +137,7 @@ _libtelnet= libtelnet
|
||||
|
||||
.if ${MK_USB} != "no"
|
||||
_libusbhid= libusbhid
|
||||
_libusb20= libusb20
|
||||
.endif
|
||||
|
||||
.include <bsd.subdir.mk>
|
||||
|
@ -60,9 +60,9 @@ USB through the USB file system interface.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_tr_close
|
||||
.Fn libusb20_tr_close pxfer
|
||||
This function will release all kernel resources associated with an USB
|
||||
.Fa xfer .
|
||||
.Fa pxfer .
|
||||
.
|
||||
This function returns zero upon success.
|
||||
.
|
||||
@ -70,13 +70,13 @@ Non-zero return values indicate a LIBUSB20_ERROR value.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_tr_open
|
||||
.Fn libusb20_tr_open pxfer max_buf_size max_frame_count ep_no
|
||||
This function will allocate kernel resources like
|
||||
.Fa MaxBufSize
|
||||
.Fa max_buf_size
|
||||
and
|
||||
.Fa MaxFrameCount
|
||||
.Fa max_frame_count
|
||||
associated with an USB
|
||||
.Fa xfer
|
||||
.Fa pxfer
|
||||
and bind the transfer to the specified
|
||||
.Fa ep_no .
|
||||
.
|
||||
@ -86,7 +86,7 @@ Non-zero return values indicate a LIBUSB20_ERROR value.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_tr_get_pointer
|
||||
.Fn libusb20_tr_get_pointer pdev tr_index
|
||||
This function will return a pointer to the allocated USB transfer according to the
|
||||
.Fa pdev
|
||||
and
|
||||
@ -97,32 +97,32 @@ This function returns NULL in case of failure.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_tr_get_time_complete
|
||||
.Fn libusb20_tr_get_time_complete pxfer
|
||||
This function will return the completion time of an USB transfer in
|
||||
millisecond units. This function is most useful for isochronous USB
|
||||
transfers when doing echo cancelling.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_tr_get_actual_frames
|
||||
.Fn libusb20_tr_get_actual_frames pxfer
|
||||
This function will return the actual number of USB frames after an USB
|
||||
transfer completed. A value of zero means that no data was transferred.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_tr_get_actual_length
|
||||
.Fn libusb20_tr_get_actual_length pxfer
|
||||
This function will return the sum of the actual length for all
|
||||
transferred USB frames for the given USB transfer.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_tr_get_max_frames
|
||||
.Fn libusb20_tr_get_max_frames pxfer
|
||||
This function will return the maximum number of USB frames that were
|
||||
allocated when an USB transfer was setup for the given USB transfer.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_tr_get_max_packet_length
|
||||
.Fn libusb20_tr_get_max_packet_length pxfer
|
||||
This function will return the maximum packet length in bytes
|
||||
associated with the given USB transfer.
|
||||
.
|
||||
@ -132,20 +132,20 @@ packets are avoided for proxy buffers.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_tr_get_max_total_length
|
||||
.Fn libusb20_tr_get_max_total_length pxfer
|
||||
This function will return the maximum value for the length sum of all
|
||||
USB frames associated with an USB transfer.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_tr_get_status
|
||||
.Fn libusb20_tr_get_status pxfer
|
||||
This function will return the status of an USB transfer.
|
||||
.
|
||||
Status values are defined by a set of LIBUSB20_TRANSFER_XXX enums.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_tr_pending
|
||||
.Fn libusb20_tr_pending pxfer
|
||||
This function will return non-zero if the given USB transfer is
|
||||
pending for completion.
|
||||
.
|
||||
@ -153,12 +153,12 @@ Else this function returns zero.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_tr_callback_wrapper
|
||||
.Fn libusb20_tr_callback_wrapper pxfer
|
||||
This is an internal function used to wrap asynchronous USB callbacks.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_tr_clear_stall_sync
|
||||
.Fn libusb20_tr_clear_stall_sync pxfer
|
||||
This is an internal function used to synchronously clear the stall on
|
||||
the given USB transfer.
|
||||
.
|
||||
@ -171,13 +171,13 @@ been called.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_tr_drain
|
||||
.Fn libusb20_tr_drain pxfer
|
||||
This function will stop the given USB transfer and will not return
|
||||
until the USB transfer has been stopped in hardware.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_tr_set_buffer
|
||||
.Fn libusb20_tr_set_buffer pxfer pbuf fr_index
|
||||
This function is used to set the
|
||||
.Fa buffer
|
||||
pointer for the given USB transfer and
|
||||
@ -188,7 +188,7 @@ Typically the frame index is zero.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_tr_set_callback
|
||||
.Fn libusb20_tr_set_callback pxfer pcallback
|
||||
This function is used to set the USB callback for asynchronous USB
|
||||
transfers.
|
||||
.
|
||||
@ -196,7 +196,7 @@ The callback type is defined by libusb20_tr_callback_t.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_tr_set_flags
|
||||
.Fn libusb20_tr_set_flags pxfer flags
|
||||
This function is used to set various USB flags for the given USB transfer.
|
||||
.Bl -tag
|
||||
.It LIBUSB20_TRANSFER_SINGLE_SHORT_NOT_OK
|
||||
@ -211,22 +211,22 @@ Will do a clear-stall before starting the transfer.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_tr_set_length
|
||||
.Fn libusb20_tr_set_length pxfer length fr_index
|
||||
This function sets the length of a given USB transfer and frame index.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_tr_set_priv_sc0
|
||||
.Fn libusb20_tr_set_priv_sc0 pxfer psc0
|
||||
This function sets private driver pointer number zero.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_tr_set_priv_sc1
|
||||
.Fn libusb20_tr_set_priv_sc1 pxfer psc1
|
||||
This function sets private driver pointer number one.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_tr_set_timeout
|
||||
.Fn libusb20_tr_set_timeout pxfer timeout
|
||||
This function sets the timeout for the given USB transfer.
|
||||
.
|
||||
A timeout value of zero means no timeout.
|
||||
@ -235,35 +235,35 @@ The timeout is given in milliseconds.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_tr_set_total_frames
|
||||
.Fn libusb20_tr_set_total_frames pxfer nframes
|
||||
This function sets the total number of frames that should be executed when the USB transfer is submitted.
|
||||
.
|
||||
The total number of USB frames must be less than the maximum number of USB frames associated with the given USB transfer.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_tr_setup_bulk
|
||||
.Fn libusb20_tr_setup_bulk pxfer pbuf length timeout
|
||||
This function is a helper function for setting up a single frame USB BULK transfer.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_tr_setup_control
|
||||
.Fn libusb20_tr_setup_control pxfer psetup pbuf timeout
|
||||
This function is a helper function for setting up a single or dual
|
||||
frame USB CONTROL transfer depending on the control transfer length.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_tr_setup_intr
|
||||
.Fn libusb20_tr_setup_intr pxfer pbuf length timeout
|
||||
This function is a helper function for setting up a single frame USB INTERRUPT transfer.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_tr_setup_isoc
|
||||
.Fn libusb20_tr_setup_isoc pxfer pbuf length fr_index
|
||||
This function is a helper function for setting up a multi frame USB ISOCHRONOUS transfer.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_tr_start
|
||||
.Fn libusb20_tr_start pxfer
|
||||
This function will get the USB transfer started, if not already
|
||||
started.
|
||||
.
|
||||
@ -273,7 +273,7 @@ This function is non-blocking.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_tr_stop
|
||||
.Fn libusb20_tr_stop pxfer
|
||||
This function will get the USB transfer stopped, if not already stopped.
|
||||
.
|
||||
This function is non-blocking, which means that the actual stop can
|
||||
@ -281,20 +281,20 @@ happen after the return of this function.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_tr_submit
|
||||
.Fn libusb20_tr_submit pxfer
|
||||
This function will get the USB transfer queued in hardware.
|
||||
.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_tr_get_priv_sc0
|
||||
.Fn libusb20_tr_get_priv_sc0 pxfer
|
||||
This function returns private driver pointer number zero associated
|
||||
with an USB transfer.
|
||||
.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_tr_get_priv_sc1
|
||||
.Fn libusb20_tr_get_priv_sc1 pxfer
|
||||
This function returns private driver pointer number one associated
|
||||
with an USB transfer.
|
||||
.
|
||||
@ -303,17 +303,17 @@ with an USB transfer.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_dev_get_backend_name
|
||||
.Fn libusb20_dev_get_backend_name pdev
|
||||
This function returns a zero terminated string describing the backend used.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_dev_get_desc
|
||||
.Fn libusb20_dev_get_desc pdev
|
||||
This function returns a zero terminated string describing the given USB device.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_dev_claim_interface
|
||||
.Fn libusb20_dev_claim_interface pdev iface_index
|
||||
This function will try to claim the given USB interface given by
|
||||
.Fa iface_index .
|
||||
This function returns zero on success else a LIBUSB20_ERROR value is
|
||||
@ -321,7 +321,7 @@ returned.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_dev_close
|
||||
.Fn libusb20_dev_close pdev
|
||||
This function will close the given USB device.
|
||||
.
|
||||
This function returns zero on success else a LIBUSB20_ERROR value is
|
||||
@ -329,7 +329,7 @@ returned.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_dev_detach_kernel_driver
|
||||
.Fn libusb20_dev_detach_kernel_driver pdev iface_index
|
||||
This function will try to detach the kernel driver for the USB interface given by
|
||||
.Fa iface_index .
|
||||
.
|
||||
@ -338,7 +338,7 @@ returned.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_dev_set_config_index
|
||||
.Fn libusb20_dev_set_config_index pdev config_index
|
||||
This function will try to set the configuration index on an USB
|
||||
device.
|
||||
.
|
||||
@ -350,12 +350,12 @@ This function returns zero on success else a LIBUSB20_ERROR value is returned.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_dev_get_debug
|
||||
.Fn libusb20_dev_get_debug pdev
|
||||
This function returns the debug level of an USB device.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_dev_get_fd
|
||||
.Fn libusb20_dev_get_fd pdev
|
||||
This function returns the file descriptor of the given USB device.
|
||||
.
|
||||
A negative value is returned when no file descriptor is present.
|
||||
@ -364,7 +364,7 @@ The file descriptor can be used for polling purposes.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_dev_kernel_driver_active
|
||||
.Fn libusb20_dev_kernel_driver_active pdev iface_index
|
||||
This function returns a non-zero value if a kernel driver is active on
|
||||
the given USB interface.
|
||||
.
|
||||
@ -372,7 +372,7 @@ Else zero is returned.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_dev_open
|
||||
.Fn libusb20_dev_open pdev transfer_max
|
||||
This function opens an USB device so that setting up USB transfers
|
||||
becomes possible.
|
||||
.
|
||||
@ -387,7 +387,7 @@ opened.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_dev_process
|
||||
.Fn libusb20_dev_process pdev
|
||||
This function is called to sync kernel USB transfers with userland USB
|
||||
transfers.
|
||||
.
|
||||
@ -397,7 +397,7 @@ detached.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_dev_release_interface
|
||||
.Fn libusb20_dev_release_interface pdev iface_index
|
||||
This function will try to release a claimed USB interface for the specified USB device.
|
||||
.
|
||||
This function returns zero on success else a LIBUSB20_ERROR value is
|
||||
@ -405,7 +405,7 @@ returned.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_dev_request_sync
|
||||
.Fn libusb20_dev_request_sync pdev psetup pdata pactlen timeout flags
|
||||
This function will perform a synchronous control request on the given
|
||||
USB device.
|
||||
.
|
||||
@ -428,7 +428,7 @@ returned.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_dev_req_string_sync
|
||||
.Fn libusb20_dev_req_string_sync pdev index lang_id pbuf len
|
||||
This function will synchronously request an USB string by language ID
|
||||
and string index into the given buffer limited by a maximum length.
|
||||
.
|
||||
@ -437,7 +437,7 @@ returned.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_dev_req_string_simple_sync
|
||||
.Fn libusb20_dev_req_string_simple_sync pdev index pbuf len
|
||||
This function will synchronously request an USB string using the
|
||||
default language ID and convert the string into ASCII before storing
|
||||
the string into the given buffer limited by a maximum length which
|
||||
@ -449,7 +449,7 @@ returned.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_dev_reset
|
||||
.Fn libusb20_dev_reset pdev
|
||||
This function will try to BUS reset the given USB device and restore
|
||||
the last set USB configuration.
|
||||
.
|
||||
@ -458,7 +458,7 @@ returned.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_dev_set_power_mode
|
||||
.Fn libusb20_dev_set_power_mode pdev power_mode
|
||||
This function sets the power mode of the USB device.
|
||||
.
|
||||
Valid power modes:
|
||||
@ -475,13 +475,13 @@ returned.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_dev_get_power_mode
|
||||
.Fn libusb20_dev_get_power_mode pdev
|
||||
This function returns the currently selected power mode for the given
|
||||
USB device.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_dev_set_alt_index
|
||||
.Fn libusb20_dev_set_alt_index pdev iface_index alt_index
|
||||
This function will try to set the given alternate index for the given
|
||||
USB interface index.
|
||||
.
|
||||
@ -490,7 +490,7 @@ returned.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_dev_set_owner
|
||||
.Fn libusb20_dev_set_owner pdev uid gid
|
||||
This function will set the ownership of the given USB device.
|
||||
.
|
||||
This function returns zero on success else a LIBUSB20_ERROR value is
|
||||
@ -498,7 +498,7 @@ returned.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_dev_set_perm
|
||||
.Fn libusb20_dev_set_perm pdev mode
|
||||
This function will set the permissions of the given USB device.
|
||||
.
|
||||
This function returns zero on success else a LIBUSB20_ERROR value is
|
||||
@ -506,7 +506,7 @@ returned.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_dev_set_iface_owner
|
||||
.Fn libusb20_dev_set_iface_owner pdev iface_index uid gid
|
||||
This function will set the ownership of the given USB interface.
|
||||
.
|
||||
This function returns zero on success else a LIBUSB20_ERROR value is
|
||||
@ -514,7 +514,7 @@ returned.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_dev_set_iface_perm
|
||||
.Fn libusb20_dev_set_iface_perm pdev iface_index mode
|
||||
This function will set the permissions of the given USB interface.
|
||||
.
|
||||
This function returns zero on success else a LIBUSB20_ERROR value is
|
||||
@ -522,7 +522,7 @@ returned.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_dev_get_owner
|
||||
.Fn libusb20_dev_get_owner pdev puid pgid
|
||||
This function will retrieve the current USB device ownership.
|
||||
.
|
||||
This function returns zero on success else a LIBUSB20_ERROR value is
|
||||
@ -530,7 +530,7 @@ returned.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_dev_get_perm
|
||||
.Fn libusb20_dev_get_perm pdev pmode
|
||||
This function will retrieve the current USB device permissions.
|
||||
.
|
||||
This function returns zero on success else a LIBUSB20_ERROR value is
|
||||
@ -538,7 +538,7 @@ returned.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_dev_get_iface_owner
|
||||
.Fn libusb20_dev_get_iface_owner pdev iface_index puid pgid
|
||||
This function will retrieve the current USB interface ownership for
|
||||
the given USB interface.
|
||||
.
|
||||
@ -547,7 +547,7 @@ returned.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_dev_get_iface_perm
|
||||
.Fn libusb20_dev_get_iface_perm pdev iface_index pmode
|
||||
This function will retrieve the current USB interface permissions for
|
||||
the given USB interface.
|
||||
.
|
||||
@ -556,7 +556,7 @@ returned.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_dev_get_device_desc
|
||||
.Fn libusb20_dev_get_device_desc pdev
|
||||
This function returns a pointer to the decoded and host endian version
|
||||
of the device descriptor.
|
||||
.
|
||||
@ -564,7 +564,7 @@ The USB device need not be opened when calling this function.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_dev_alloc_config
|
||||
.Fn libusb20_dev_alloc_config pdev config_index
|
||||
This function will read out and decode the USB config descriptor for
|
||||
the given USB device and config index. This function returns a pointer
|
||||
to the decoded configuration which must eventually be passed to
|
||||
@ -572,24 +572,24 @@ free(). NULL is returned in case of failure.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_dev_alloc(void)
|
||||
.Fn libusb20_dev_alloc void
|
||||
This is an internal function to allocate a new USB device.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_dev_get_address
|
||||
.Fn libusb20_dev_get_address pdev
|
||||
This function returns the internal and not necessarily the real
|
||||
hardware address of the given USB device.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_dev_get_bus_number
|
||||
.Fn libusb20_dev_get_bus_number pdev
|
||||
This function return the internal bus number which the given USB
|
||||
device belongs to.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_dev_get_mode
|
||||
.Fn libusb20_dev_get_mode pdev
|
||||
This function returns the current operation mode of the USB entity.
|
||||
.
|
||||
Valid return values are:
|
||||
@ -600,7 +600,7 @@ Valid return values are:
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_dev_get_speed
|
||||
.Fn libusb20_dev_get_speed pdev
|
||||
This function returns the current speed of the given USB device.
|
||||
.
|
||||
.Bl -tag
|
||||
@ -614,24 +614,24 @@ This function returns the current speed of the given USB device.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_dev_get_config_index
|
||||
.Fn libusb20_dev_get_config_index pdev
|
||||
This function returns the currently select config index for the given
|
||||
USB device.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_dev_free
|
||||
.Fn libusb20_dev_free pdev
|
||||
This function will free the given USB device and all associated USB
|
||||
transfers.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_dev_set_debug
|
||||
.Fn libusb20_dev_set_debug pdev debug_level
|
||||
This function will set the debug level for the given USB device.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_dev_wait_process
|
||||
.Fn libusb20_dev_wait_process pdev timeout
|
||||
This function will wait until a pending USB transfer has completed on
|
||||
the given USB device.
|
||||
.
|
||||
@ -641,7 +641,7 @@ function.
|
||||
.
|
||||
.Sh USB BUS OPERATIONS
|
||||
.
|
||||
.Fn libusb20_bus_set_owner
|
||||
.Fn libusb20_bus_set_owner pbackend bus_index uid gid
|
||||
This function will set the ownership for the given USB bus.
|
||||
.
|
||||
This function returns zero on success else a LIBUSB20_ERROR value is
|
||||
@ -649,7 +649,7 @@ returned.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_bus_set_perm
|
||||
.Fn libusb20_bus_set_perm pbackend bus_index mode
|
||||
This function will set the permissions for the given USB bus.
|
||||
.
|
||||
This function returns zero on success else a LIBUSB20_ERROR value is
|
||||
@ -657,7 +657,7 @@ returned.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_bus_get_owner
|
||||
.Fn libusb20_bus_get_owner pbackend bus_index puid pgid
|
||||
This function will retrieve the ownership for the given USB bus.
|
||||
.
|
||||
This function returns zero on success else a LIBUSB20_ERROR value is
|
||||
@ -665,7 +665,7 @@ returned.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_bus_get_perm
|
||||
.Fn libusb20_bus_get_perm pbackend bus_index pmode
|
||||
This function will retrieve the permissions for the given USB bus.
|
||||
.
|
||||
This function returns zero on success else a LIBUSB20_ERROR value is
|
||||
@ -674,7 +674,7 @@ returned.
|
||||
.
|
||||
.Sh USB BACKEND OPERATIONS
|
||||
.
|
||||
.Fn libusb20_be_get_dev_quirk
|
||||
.Fn libusb20_be_get_dev_quirk pbackend index pquirk
|
||||
This function will return the device quirk according to
|
||||
.Fa index
|
||||
into the libusb20_quirk structure pointed to by
|
||||
@ -687,7 +687,7 @@ returned.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_be_get_quirk_name
|
||||
.Fn libusb20_be_get_quirk_name pbackend index pquirk
|
||||
This function will return the quirk name according to
|
||||
.Fa index
|
||||
into the libusb20_quirk structure pointed to by
|
||||
@ -700,7 +700,7 @@ returned.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_be_add_dev_quirk
|
||||
.Fn libusb20_be_add_dev_quirk pbackend pquirk
|
||||
This function will add the libusb20_quirk structure pointed to by the
|
||||
.Fa pq
|
||||
argument into the device quirk list.
|
||||
@ -713,7 +713,7 @@ returned.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_be_remove_dev_quirk
|
||||
.Fn libusb20_be_remove_dev_quirk pbackend pquirk
|
||||
This function will remove the quirk matching the libusb20_quirk structure pointed to by the
|
||||
.Fa pq
|
||||
argument from the device quirk list.
|
||||
@ -726,7 +726,7 @@ returned.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_be_set_owner
|
||||
.Fn libusb20_be_set_owner pbackend uid gid
|
||||
This function will set the ownership for the given backend.
|
||||
.
|
||||
This function returns zero on success else a LIBUSB20_ERROR value is
|
||||
@ -734,7 +734,7 @@ returned.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_be_set_perm
|
||||
.Fn libusb20_be_set_perm pbackend mode
|
||||
This function will set the permissions for the given backend.
|
||||
.
|
||||
This function returns zero on success else a LIBUSB20_ERROR value is
|
||||
@ -742,7 +742,7 @@ returned.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_be_get_owner
|
||||
.Fn libusb20_be_get_owner pbackend puid pgid
|
||||
This function will retrieve the ownership of the given backend.
|
||||
.
|
||||
This function returns zero on success else a LIBUSB20_ERROR value is
|
||||
@ -750,7 +750,7 @@ returned.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_be_get_perm
|
||||
.Fn libusb20_be_get_perm pbackend pmode
|
||||
This function will retrieve the permissions of the given backend.
|
||||
.
|
||||
.
|
||||
@ -759,20 +759,20 @@ returned.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_be_alloc
|
||||
.Fn libusb20_be_alloc pmethods
|
||||
This is an internal function to allocate a USB backend.
|
||||
.
|
||||
.Pp
|
||||
.Fn libusb20_be_alloc_default
|
||||
.Fn libusb20_be_alloc_freebsd
|
||||
.Fn libusb20_be_alloc_linux
|
||||
.Fn libusb20_be_alloc_default void
|
||||
.Fn libusb20_be_alloc_freebsd void
|
||||
.Fn libusb20_be_alloc_linux void
|
||||
These functions are used to allocate a specific USB backend or the
|
||||
operating system default USB backend. Allocating a backend is a way to
|
||||
scan for currently present USB devices.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_be_device_foreach
|
||||
.Fn libusb20_be_device_foreach pbackend pdev
|
||||
This function is used to iterate USB devices present in a USB backend.
|
||||
.
|
||||
The starting value of
|
||||
@ -785,7 +785,7 @@ If NULL is returned the end of the USB device list has been reached.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_be_dequeue_device
|
||||
.Fn libusb20_be_dequeue_device pbackend pdev
|
||||
This function will dequeue the given USB device pointer from the
|
||||
backend USB device list.
|
||||
.
|
||||
@ -793,20 +793,20 @@ Dequeued USB devices will not be freed when the backend is freed.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_be_enqueue_device
|
||||
.Fn libusb20_be_enqueue_device pbackend pdev
|
||||
This function will enqueue the given USB device pointer in the backend USB device list.
|
||||
.
|
||||
Enqueued USB devices will get freed when the backend is freed.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_be_free
|
||||
.Fn libusb20_be_free pbackend
|
||||
This function will free the given backend and all USB devices in its device list.
|
||||
.
|
||||
.
|
||||
.Sh USB DESCRIPTOR PARSING
|
||||
.
|
||||
.Fn libusb20_me_get_1
|
||||
.Fn libusb20_me_get_1 pie offset
|
||||
This function will return a byte at the given byte offset of a message
|
||||
entity.
|
||||
.
|
||||
@ -814,7 +814,7 @@ This function is safe against invalid offsets.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_me_get_2
|
||||
.Fn libusb20_me_get_2 pie offset
|
||||
This function will return a little endian 16-bit value at the given byte offset of a message
|
||||
entity.
|
||||
.
|
||||
@ -822,7 +822,7 @@ This function is safe against invalid offsets.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_me_encode
|
||||
.Fn libusb20_me_encode pbuf len pdecoded
|
||||
This function will encode a so-called *DECODED structure into binary
|
||||
format.
|
||||
.
|
||||
@ -834,7 +834,7 @@ location.
|
||||
.
|
||||
.Pp
|
||||
.
|
||||
.Fn libusb20_me_decode
|
||||
.Fn libusb20_me_decode pbuf len pdecoded
|
||||
This function will decode a binary structure into a so-called *DECODED
|
||||
structure.
|
||||
.
|
||||
|
@ -550,6 +550,9 @@ libusb20_dev_open(struct libusb20_device *pdev, uint16_t nTransferMax)
|
||||
xfer->callback = &dummy_callback;
|
||||
}
|
||||
|
||||
/* set "nTransfer" early */
|
||||
pdev->nTransfer = nTransferMax;
|
||||
|
||||
error = (pdev->beMethods->open_device) (pdev, nTransferMax);
|
||||
|
||||
if (error) {
|
||||
@ -562,7 +565,6 @@ libusb20_dev_open(struct libusb20_device *pdev, uint16_t nTransferMax)
|
||||
pdev->nTransfer = 0;
|
||||
} else {
|
||||
pdev->is_opened = 1;
|
||||
pdev->nTransfer = nTransferMax;
|
||||
}
|
||||
return (error);
|
||||
}
|
||||
@ -647,7 +649,7 @@ libusb20_dev_request_sync(struct libusb20_device *pdev,
|
||||
|
||||
int
|
||||
libusb20_dev_req_string_sync(struct libusb20_device *pdev,
|
||||
uint8_t index, uint16_t langid, void *ptr, uint16_t len)
|
||||
uint8_t str_index, uint16_t langid, void *ptr, uint16_t len)
|
||||
{
|
||||
struct LIBUSB20_CONTROL_SETUP_DECODED req;
|
||||
int error;
|
||||
@ -667,7 +669,7 @@ libusb20_dev_req_string_sync(struct libusb20_device *pdev,
|
||||
LIBUSB20_RECIPIENT_DEVICE |
|
||||
LIBUSB20_ENDPOINT_IN;
|
||||
req.bRequest = LIBUSB20_REQUEST_GET_DESCRIPTOR;
|
||||
req.wValue = (LIBUSB20_DT_STRING << 8) | index;
|
||||
req.wValue = (LIBUSB20_DT_STRING << 8) | str_index;
|
||||
req.wIndex = langid;
|
||||
req.wLength = 4; /* bytes */
|
||||
|
||||
@ -695,7 +697,7 @@ libusb20_dev_req_string_sync(struct libusb20_device *pdev,
|
||||
|
||||
int
|
||||
libusb20_dev_req_string_simple_sync(struct libusb20_device *pdev,
|
||||
uint8_t index, void *ptr, uint16_t len)
|
||||
uint8_t str_index, void *ptr, uint16_t len)
|
||||
{
|
||||
char *buf;
|
||||
int error;
|
||||
@ -712,26 +714,23 @@ libusb20_dev_req_string_simple_sync(struct libusb20_device *pdev,
|
||||
/* too short buffer */
|
||||
return (LIBUSB20_ERROR_INVALID_PARAM);
|
||||
}
|
||||
/*
|
||||
* Make sure that there is sensible contents in the buffer in case
|
||||
* of an error:
|
||||
*/
|
||||
*(uint8_t *)ptr = 0;
|
||||
|
||||
error = libusb20_dev_req_string_sync(pdev,
|
||||
0, 0, temp, sizeof(temp));
|
||||
if (error < 0)
|
||||
if (error < 0) {
|
||||
*(uint8_t *)ptr = 0; /* zero terminate */
|
||||
return (error);
|
||||
|
||||
}
|
||||
langid = temp[2] | (temp[3] << 8);
|
||||
|
||||
error = libusb20_dev_req_string_sync(pdev, index,
|
||||
error = libusb20_dev_req_string_sync(pdev, str_index,
|
||||
langid, temp, sizeof(temp));
|
||||
if (error < 0)
|
||||
if (error < 0) {
|
||||
*(uint8_t *)ptr = 0; /* zero terminate */
|
||||
return (error);
|
||||
|
||||
}
|
||||
if (temp[0] < 2) {
|
||||
/* string length is too short */
|
||||
*(uint8_t *)ptr = 0; /* zero terminate */
|
||||
return (LIBUSB20_ERROR_OTHER);
|
||||
}
|
||||
/* reserve one byte for terminating zero */
|
||||
@ -762,14 +761,16 @@ libusb20_dev_req_string_simple_sync(struct libusb20_device *pdev,
|
||||
*buf = c >> 8;
|
||||
swap = 2;
|
||||
} else {
|
||||
*buf = '.';
|
||||
/* skip invalid character */
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
* Filter by default - we don't allow greater and less than
|
||||
* signs because they might confuse the dmesg printouts!
|
||||
*/
|
||||
if ((*buf == '<') || (*buf == '>') || (!isprint(*buf))) {
|
||||
*buf = '.';
|
||||
/* skip invalid character */
|
||||
continue;
|
||||
}
|
||||
buf++;
|
||||
}
|
||||
@ -836,7 +837,7 @@ uint8_t
|
||||
libusb20_dev_get_config_index(struct libusb20_device *pdev)
|
||||
{
|
||||
int error;
|
||||
uint8_t index;
|
||||
uint8_t cfg_index;
|
||||
uint8_t do_close;
|
||||
|
||||
if (!pdev->is_opened) {
|
||||
@ -850,16 +851,16 @@ libusb20_dev_get_config_index(struct libusb20_device *pdev)
|
||||
do_close = 0;
|
||||
}
|
||||
|
||||
error = (pdev->methods->get_config_index) (pdev, &index);
|
||||
error = (pdev->methods->get_config_index) (pdev, &cfg_index);
|
||||
if (error) {
|
||||
index = 0 - 1; /* current config index */
|
||||
cfg_index = 0 - 1; /* current config index */
|
||||
}
|
||||
if (do_close) {
|
||||
if (libusb20_dev_close(pdev)) {
|
||||
/* ignore */
|
||||
}
|
||||
}
|
||||
return (index);
|
||||
return (cfg_index);
|
||||
}
|
||||
|
||||
uint8_t
|
||||
@ -887,7 +888,7 @@ libusb20_dev_process(struct libusb20_device *pdev)
|
||||
void
|
||||
libusb20_dev_wait_process(struct libusb20_device *pdev, int timeout)
|
||||
{
|
||||
struct pollfd pfd[2];
|
||||
struct pollfd pfd[1];
|
||||
|
||||
if (!pdev->is_opened) {
|
||||
return;
|
||||
@ -895,11 +896,8 @@ libusb20_dev_wait_process(struct libusb20_device *pdev, int timeout)
|
||||
pfd[0].fd = pdev->file;
|
||||
pfd[0].events = (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM);
|
||||
pfd[0].revents = 0;
|
||||
pfd[1].fd = 0; /* standard input */
|
||||
pfd[1].events = (POLLIN | POLLRDNORM);
|
||||
pfd[1].revents = 0;
|
||||
|
||||
if (poll(pfd, 2, timeout)) {
|
||||
if (poll(pfd, 1, timeout)) {
|
||||
/* ignore any error */
|
||||
}
|
||||
return;
|
||||
@ -1071,16 +1069,16 @@ libusb20_bus_get_perm(struct libusb20_backend *pbe, uint8_t bus, mode_t *mode)
|
||||
|
||||
int
|
||||
libusb20_be_get_dev_quirk(struct libusb20_backend *pbe,
|
||||
uint16_t index, struct libusb20_quirk *pq)
|
||||
uint16_t quirk_index, struct libusb20_quirk *pq)
|
||||
{
|
||||
return ((pbe->methods->root_get_dev_quirk) (pbe, index, pq));
|
||||
return ((pbe->methods->root_get_dev_quirk) (pbe, quirk_index, pq));
|
||||
}
|
||||
|
||||
int
|
||||
libusb20_be_get_quirk_name(struct libusb20_backend *pbe,
|
||||
uint16_t index, struct libusb20_quirk *pq)
|
||||
uint16_t quirk_index, struct libusb20_quirk *pq)
|
||||
{
|
||||
return ((pbe->methods->root_get_quirk_name) (pbe, index, pq));
|
||||
return ((pbe->methods->root_get_quirk_name) (pbe, quirk_index, pq));
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -199,7 +199,7 @@ struct libusb20_quirk {
|
||||
/* USB transfer operations */
|
||||
|
||||
int libusb20_tr_close(struct libusb20_transfer *xfer);
|
||||
int libusb20_tr_open(struct libusb20_transfer *xfer, uint32_t pMaxBufSize, uint32_t MaxFrameCount, uint8_t ep_no);
|
||||
int libusb20_tr_open(struct libusb20_transfer *xfer, uint32_t max_buf_size, uint32_t max_frame_count, uint8_t ep_no);
|
||||
struct libusb20_transfer *libusb20_tr_get_pointer(struct libusb20_device *pdev, uint16_t tr_index);
|
||||
uint16_t libusb20_tr_get_time_complete(struct libusb20_transfer *xfer);
|
||||
uint32_t libusb20_tr_get_actual_frames(struct libusb20_transfer *xfer);
|
||||
@ -297,6 +297,7 @@ struct libusb20_backend *libusb20_be_alloc(const struct libusb20_backend_methods
|
||||
struct libusb20_backend *libusb20_be_alloc_default(void);
|
||||
struct libusb20_backend *libusb20_be_alloc_freebsd(void);
|
||||
struct libusb20_backend *libusb20_be_alloc_linux(void);
|
||||
struct libusb20_backend *libusb20_be_alloc_ugen20(void);
|
||||
struct libusb20_device *libusb20_be_device_foreach(struct libusb20_backend *pbe, struct libusb20_device *pdev);
|
||||
void libusb20_be_dequeue_device(struct libusb20_backend *pbe, struct libusb20_device *pdev);
|
||||
void libusb20_be_enqueue_device(struct libusb20_backend *pbe, struct libusb20_device *pdev);
|
||||
|
@ -131,7 +131,7 @@ usb_get_transfer_by_ep_no(usb_dev_handle * dev, uint8_t ep_no)
|
||||
x = (ep_no & LIBUSB20_ENDPOINT_ADDRESS_MASK) * 2;
|
||||
|
||||
if (ep_no & LIBUSB20_ENDPOINT_DIR_MASK) {
|
||||
/* this is a IN endpoint */
|
||||
/* this is an IN endpoint */
|
||||
x |= 1;
|
||||
}
|
||||
speed = libusb20_dev_get_speed(pdev);
|
||||
@ -194,13 +194,13 @@ usb_close(usb_dev_handle * dev)
|
||||
}
|
||||
|
||||
int
|
||||
usb_get_string(usb_dev_handle * dev, int index,
|
||||
usb_get_string(usb_dev_handle * dev, int strindex,
|
||||
int langid, char *buf, size_t buflen)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = libusb20_dev_req_string_sync((void *)dev,
|
||||
index, langid, buf, buflen);
|
||||
strindex, langid, buf, buflen);
|
||||
|
||||
if (err)
|
||||
return (-1);
|
||||
@ -209,13 +209,13 @@ usb_get_string(usb_dev_handle * dev, int index,
|
||||
}
|
||||
|
||||
int
|
||||
usb_get_string_simple(usb_dev_handle * dev, int index,
|
||||
usb_get_string_simple(usb_dev_handle * dev, int strindex,
|
||||
char *buf, size_t buflen)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = libusb20_dev_req_string_simple_sync((void *)dev,
|
||||
index, buf, buflen);
|
||||
strindex, buf, buflen);
|
||||
|
||||
if (err)
|
||||
return (-1);
|
||||
@ -225,23 +225,23 @@ usb_get_string_simple(usb_dev_handle * dev, int index,
|
||||
|
||||
int
|
||||
usb_get_descriptor_by_endpoint(usb_dev_handle * udev, int ep, uint8_t type,
|
||||
uint8_t index, void *buf, int size)
|
||||
uint8_t ep_index, void *buf, int size)
|
||||
{
|
||||
memset(buf, 0, size);
|
||||
|
||||
return (usb_control_msg(udev, ep | USB_ENDPOINT_IN,
|
||||
USB_REQ_GET_DESCRIPTOR, (type << 8) + index, 0,
|
||||
USB_REQ_GET_DESCRIPTOR, (type << 8) + ep_index, 0,
|
||||
buf, size, 1000));
|
||||
}
|
||||
|
||||
int
|
||||
usb_get_descriptor(usb_dev_handle * udev, uint8_t type, uint8_t index,
|
||||
usb_get_descriptor(usb_dev_handle * udev, uint8_t type, uint8_t desc_index,
|
||||
void *buf, int size)
|
||||
{
|
||||
memset(buf, 0, size);
|
||||
|
||||
return (usb_control_msg(udev, USB_ENDPOINT_IN, USB_REQ_GET_DESCRIPTOR,
|
||||
(type << 8) + index, 0, buf, size, 1000));
|
||||
(type << 8) + desc_index, 0, buf, size, 1000));
|
||||
}
|
||||
|
||||
int
|
||||
@ -616,33 +616,37 @@ int
|
||||
usb_bulk_write(usb_dev_handle * dev, int ep, char *bytes,
|
||||
int size, int timeout)
|
||||
{
|
||||
return (usb_std_io(dev, ep, bytes, size, timeout, 0));
|
||||
return (usb_std_io(dev, ep & ~USB_ENDPOINT_DIR_MASK,
|
||||
bytes, size, timeout, 0));
|
||||
}
|
||||
|
||||
int
|
||||
usb_bulk_read(usb_dev_handle * dev, int ep, char *bytes,
|
||||
int size, int timeout)
|
||||
{
|
||||
return (usb_std_io(dev, ep, bytes, size, timeout, 0));
|
||||
return (usb_std_io(dev, ep | USB_ENDPOINT_DIR_MASK,
|
||||
bytes, size, timeout, 0));
|
||||
}
|
||||
|
||||
int
|
||||
usb_interrupt_write(usb_dev_handle * dev, int ep, char *bytes,
|
||||
int size, int timeout)
|
||||
{
|
||||
return (usb_std_io(dev, ep, bytes, size, timeout, 1));
|
||||
return (usb_std_io(dev, ep & ~USB_ENDPOINT_DIR_MASK,
|
||||
bytes, size, timeout, 1));
|
||||
}
|
||||
|
||||
int
|
||||
usb_interrupt_read(usb_dev_handle * dev, int ep, char *bytes,
|
||||
int size, int timeout)
|
||||
{
|
||||
return (usb_std_io(dev, ep, bytes, size, timeout, 1));
|
||||
return (usb_std_io(dev, ep | USB_ENDPOINT_DIR_MASK,
|
||||
bytes, size, timeout, 1));
|
||||
}
|
||||
|
||||
int
|
||||
usb_control_msg(usb_dev_handle * dev, int requesttype, int request,
|
||||
int value, int index, char *bytes, int size, int timeout)
|
||||
int value, int wIndex, char *bytes, int size, int timeout)
|
||||
{
|
||||
struct LIBUSB20_CONTROL_SETUP_DECODED req;
|
||||
int err;
|
||||
@ -653,7 +657,7 @@ usb_control_msg(usb_dev_handle * dev, int requesttype, int request,
|
||||
req.bmRequestType = requesttype;
|
||||
req.bRequest = request;
|
||||
req.wValue = value;
|
||||
req.wIndex = index;
|
||||
req.wIndex = wIndex;
|
||||
req.wLength = size;
|
||||
|
||||
err = libusb20_dev_request_sync((void *)dev, &req, bytes,
|
||||
@ -666,11 +670,40 @@ usb_control_msg(usb_dev_handle * dev, int requesttype, int request,
|
||||
}
|
||||
|
||||
int
|
||||
usb_set_configuration(usb_dev_handle * dev, int configuration)
|
||||
usb_set_configuration(usb_dev_handle * udev, int bConfigurationValue)
|
||||
{
|
||||
struct usb_device *dev;
|
||||
int err;
|
||||
uint8_t i;
|
||||
|
||||
err = libusb20_dev_set_config_index((void *)dev, configuration);
|
||||
/*
|
||||
* Need to translate from "bConfigurationValue" to
|
||||
* configuration index:
|
||||
*/
|
||||
|
||||
if (bConfigurationValue == 0) {
|
||||
/* unconfigure */
|
||||
i = 255;
|
||||
} else {
|
||||
/* lookup configuration index */
|
||||
dev = usb_device(udev);
|
||||
|
||||
/* check if the configuration array is not there */
|
||||
if (dev->config == NULL) {
|
||||
return (-1);
|
||||
}
|
||||
for (i = 0;; i++) {
|
||||
if (i == dev->descriptor.bNumConfigurations) {
|
||||
/* "bConfigurationValue" not found */
|
||||
return (-1);
|
||||
}
|
||||
if ((dev->config + i)->bConfigurationValue == bConfigurationValue) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
err = libusb20_dev_set_config_index((void *)udev, i);
|
||||
|
||||
if (err)
|
||||
return (-1);
|
||||
@ -754,7 +787,7 @@ usb_reset(usb_dev_handle * dev)
|
||||
return (0);
|
||||
}
|
||||
|
||||
char *
|
||||
const char *
|
||||
usb_strerror(void)
|
||||
{
|
||||
/* TODO */
|
||||
|
@ -291,7 +291,7 @@ int usb_set_altinterface(usb_dev_handle * dev, int alternate);
|
||||
int usb_resetep(usb_dev_handle * dev, unsigned int ep);
|
||||
int usb_clear_halt(usb_dev_handle * dev, unsigned int ep);
|
||||
int usb_reset(usb_dev_handle * dev);
|
||||
char *usb_strerror(void);
|
||||
const char *usb_strerror(void);
|
||||
void usb_init(void);
|
||||
void usb_set_debug(int level);
|
||||
int usb_find_busses(void);
|
||||
|
@ -84,8 +84,8 @@ libusb20_parse_config_desc(const void *config_desc)
|
||||
/* get "wTotalLength" and setup "pcdesc" */
|
||||
pcdesc.ptr = LIBUSB20_ADD_BYTES(config_desc, 0);
|
||||
pcdesc.len =
|
||||
((uint8_t *)config_desc)[2] |
|
||||
(((uint8_t *)config_desc)[3] << 8);
|
||||
((const uint8_t *)config_desc)[2] |
|
||||
(((const uint8_t *)config_desc)[3] << 8);
|
||||
pcdesc.type = LIBUSB20_ME_IS_RAW;
|
||||
|
||||
/* descriptor pre-scan */
|
||||
@ -238,7 +238,7 @@ const uint8_t *
|
||||
libusb20_desc_foreach(const struct libusb20_me_struct *pdesc,
|
||||
const uint8_t *psubdesc)
|
||||
{
|
||||
void *end;
|
||||
const void *end;
|
||||
|
||||
if (pdesc == NULL) {
|
||||
return (NULL);
|
||||
@ -250,8 +250,8 @@ libusb20_desc_foreach(const struct libusb20_me_struct *pdesc,
|
||||
} else {
|
||||
psubdesc = LIBUSB20_ADD_BYTES(psubdesc, psubdesc[0]);
|
||||
}
|
||||
return (((((void *)psubdesc) >= ((void *)(pdesc->ptr))) &&
|
||||
(((void *)psubdesc) < end) &&
|
||||
return (((((const void *)psubdesc) >= ((void *)(pdesc->ptr))) &&
|
||||
(((const void *)psubdesc) < end) &&
|
||||
(LIBUSB20_ADD_BYTES(psubdesc, psubdesc[0]) >= ((void *)(pdesc->ptr))) &&
|
||||
(LIBUSB20_ADD_BYTES(psubdesc, psubdesc[0]) <= end) &&
|
||||
(psubdesc[0] >= 3)) ? psubdesc : NULL);
|
||||
@ -306,7 +306,7 @@ libusb20_me_encode(void *ptr, uint16_t len, const void *pd)
|
||||
len_old = len;
|
||||
buf = ptr;
|
||||
pd_offset = sizeof(void *);
|
||||
pf = (*((struct libusb20_me_format **)pd))->format;
|
||||
pf = (*((struct libusb20_me_format *const *)pd))->format;
|
||||
|
||||
/* scan */
|
||||
|
||||
|
@ -63,7 +63,7 @@ extern "C" {
|
||||
#define LIBUSB20_MIN(a,b) (((a) < (b)) ? (a) : (b))
|
||||
|
||||
#define LIBUSB20_ADD_BYTES(ptr,off) \
|
||||
((void *)(((const uint8_t *)(ptr)) + (off)))
|
||||
((void *)(((const uint8_t *)(ptr)) + (off) - ((const uint8_t *)0)))
|
||||
|
||||
/* basic message elements */
|
||||
enum {
|
||||
|
@ -307,12 +307,57 @@ ugen20_init_backend(struct libusb20_backend *pbe)
|
||||
return (0); /* success */
|
||||
}
|
||||
|
||||
static int
|
||||
ugen20_tr_renew(struct libusb20_device *pdev)
|
||||
{
|
||||
struct usb2_fs_uninit fs_uninit;
|
||||
struct usb2_fs_init fs_init;
|
||||
struct usb2_fs_endpoint *pfse;
|
||||
int error;
|
||||
uint32_t size;
|
||||
uint16_t nMaxTransfer;
|
||||
|
||||
nMaxTransfer = pdev->nTransfer;
|
||||
error = 0;
|
||||
|
||||
if (nMaxTransfer == 0) {
|
||||
goto done;
|
||||
}
|
||||
size = nMaxTransfer * sizeof(*pfse);
|
||||
|
||||
if (pdev->privBeData != NULL) {
|
||||
memset(&fs_uninit, 0, sizeof(fs_uninit));
|
||||
if (ioctl(pdev->file, USB_FS_UNINIT, &fs_uninit)) {
|
||||
/* ignore any errors of this kind */
|
||||
}
|
||||
} else {
|
||||
pfse = malloc(size);
|
||||
if (pfse == NULL) {
|
||||
error = LIBUSB20_ERROR_NO_MEM;
|
||||
goto done;
|
||||
}
|
||||
pdev->privBeData = pfse;
|
||||
}
|
||||
|
||||
/* reset endpoint data */
|
||||
memset(pdev->privBeData, 0, size);
|
||||
|
||||
memset(&fs_init, 0, sizeof(fs_init));
|
||||
|
||||
fs_init.pEndpoints = pdev->privBeData;
|
||||
fs_init.ep_index_max = nMaxTransfer;
|
||||
|
||||
if (ioctl(pdev->file, USB_FS_INIT, &fs_init)) {
|
||||
error = LIBUSB20_ERROR_OTHER;
|
||||
goto done;
|
||||
}
|
||||
done:
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
ugen20_open_device(struct libusb20_device *pdev, uint16_t nMaxTransfer)
|
||||
{
|
||||
struct usb2_fs_endpoint *pfse = NULL;
|
||||
struct usb2_fs_init fs_init = { /* zero */ };
|
||||
uint32_t size;
|
||||
uint32_t plugtime;
|
||||
char buf[64];
|
||||
int f;
|
||||
@ -345,36 +390,27 @@ ugen20_open_device(struct libusb20_device *pdev, uint16_t nMaxTransfer)
|
||||
error = LIBUSB20_ERROR_NO_DEVICE;
|
||||
goto done;
|
||||
}
|
||||
if (nMaxTransfer != 0) {
|
||||
/* need to set this before "tr_renew()" */
|
||||
pdev->file = f;
|
||||
pdev->file_ctrl = g;
|
||||
|
||||
size = nMaxTransfer * sizeof(*pfse);
|
||||
|
||||
pfse = malloc(size);
|
||||
if (!pfse) {
|
||||
error = LIBUSB20_ERROR_NO_MEM;
|
||||
goto done;
|
||||
}
|
||||
memset(pfse, 0, size);
|
||||
|
||||
fs_init.pEndpoints = pfse;
|
||||
fs_init.ep_index_max = nMaxTransfer;
|
||||
|
||||
if (ioctl(f, USB_FS_INIT, &fs_init)) {
|
||||
error = LIBUSB20_ERROR_OTHER;
|
||||
goto done;
|
||||
}
|
||||
/* renew all USB transfers */
|
||||
error = ugen20_tr_renew(pdev);
|
||||
if (error) {
|
||||
goto done;
|
||||
}
|
||||
/* set methods */
|
||||
pdev->methods = &libusb20_ugen20_device_methods;
|
||||
pdev->privBeData = pfse;
|
||||
pdev->file = f;
|
||||
pdev->file_ctrl = g;
|
||||
error = 0;
|
||||
|
||||
done:
|
||||
if (error) {
|
||||
if (pfse) {
|
||||
free(pfse);
|
||||
if (pdev->privBeData) {
|
||||
/* cleanup after "tr_renew()" */
|
||||
free(pdev->privBeData);
|
||||
pdev->privBeData = NULL;
|
||||
}
|
||||
pdev->file = -1;
|
||||
pdev->file_ctrl = -1;
|
||||
close(f);
|
||||
close(g);
|
||||
}
|
||||
@ -384,10 +420,11 @@ ugen20_open_device(struct libusb20_device *pdev, uint16_t nMaxTransfer)
|
||||
static int
|
||||
ugen20_close_device(struct libusb20_device *pdev)
|
||||
{
|
||||
struct usb2_fs_uninit fs_uninit = { /* zero */ };
|
||||
struct usb2_fs_uninit fs_uninit;
|
||||
int error = 0;
|
||||
|
||||
if (pdev->privBeData) {
|
||||
memset(&fs_uninit, 0, sizeof(fs_uninit));
|
||||
if (ioctl(pdev->file, USB_FS_UNINIT, &fs_uninit)) {
|
||||
error = LIBUSB20_ERROR_OTHER;
|
||||
}
|
||||
@ -410,17 +447,19 @@ ugen20_exit_backend(struct libusb20_backend *pbe)
|
||||
|
||||
static int
|
||||
ugen20_get_config_desc_full(struct libusb20_device *pdev,
|
||||
uint8_t **ppbuf, uint16_t *plen, uint8_t index)
|
||||
uint8_t **ppbuf, uint16_t *plen, uint8_t cfg_index)
|
||||
{
|
||||
struct usb2_gen_descriptor gen_desc = { /* zero */ };
|
||||
struct usb2_gen_descriptor gen_desc;
|
||||
struct usb2_config_descriptor cdesc;
|
||||
uint8_t *ptr;
|
||||
uint16_t len;
|
||||
int error;
|
||||
|
||||
memset(&gen_desc, 0, sizeof(gen_desc));
|
||||
|
||||
gen_desc.ugd_data = &cdesc;
|
||||
gen_desc.ugd_maxlen = sizeof(cdesc);
|
||||
gen_desc.ugd_config_index = index;
|
||||
gen_desc.ugd_config_index = cfg_index;
|
||||
|
||||
error = ioctl(pdev->file_ctrl, USB_GET_FULL_DESC, &gen_desc);
|
||||
if (error) {
|
||||
@ -466,14 +505,14 @@ ugen20_get_config_index(struct libusb20_device *pdev, uint8_t *pindex)
|
||||
}
|
||||
|
||||
static int
|
||||
ugen20_set_config_index(struct libusb20_device *pdev, uint8_t index)
|
||||
ugen20_set_config_index(struct libusb20_device *pdev, uint8_t cfg_index)
|
||||
{
|
||||
int temp = index;
|
||||
int temp = cfg_index;
|
||||
|
||||
if (ioctl(pdev->file_ctrl, USB_SET_CONFIG, &temp)) {
|
||||
return (LIBUSB20_ERROR_OTHER);
|
||||
}
|
||||
return (0);
|
||||
return (ugen20_tr_renew(pdev));
|
||||
}
|
||||
|
||||
static int
|
||||
@ -502,7 +541,9 @@ static int
|
||||
ugen20_set_alt_index(struct libusb20_device *pdev,
|
||||
uint8_t iface_index, uint8_t alt_index)
|
||||
{
|
||||
struct usb2_alt_interface alt_iface = { /* zero */ };
|
||||
struct usb2_alt_interface alt_iface;
|
||||
|
||||
memset(&alt_iface, 0, sizeof(alt_iface));
|
||||
|
||||
alt_iface.uai_interface_index = iface_index;
|
||||
alt_iface.uai_alt_index = alt_index;
|
||||
@ -510,7 +551,7 @@ ugen20_set_alt_index(struct libusb20_device *pdev,
|
||||
if (ioctl(pdev->file_ctrl, USB_SET_ALTINTERFACE, &alt_iface)) {
|
||||
return (LIBUSB20_ERROR_OTHER);
|
||||
}
|
||||
return (0);
|
||||
return (ugen20_tr_renew(pdev));
|
||||
}
|
||||
|
||||
static int
|
||||
@ -521,7 +562,7 @@ ugen20_reset_device(struct libusb20_device *pdev)
|
||||
if (ioctl(pdev->file_ctrl, USB_DEVICEENUMERATE, &temp)) {
|
||||
return (LIBUSB20_ERROR_OTHER);
|
||||
}
|
||||
return (0);
|
||||
return (ugen20_tr_renew(pdev));
|
||||
}
|
||||
|
||||
static int
|
||||
@ -615,7 +656,9 @@ ugen20_do_request_sync(struct libusb20_device *pdev,
|
||||
struct LIBUSB20_CONTROL_SETUP_DECODED *setup,
|
||||
void *data, uint16_t *pactlen, uint32_t timeout, uint8_t flags)
|
||||
{
|
||||
struct usb2_ctl_request req = { /* zero */ };
|
||||
struct usb2_ctl_request req;
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
|
||||
req.ucr_data = data;
|
||||
if (!(flags & LIBUSB20_TRANSFER_SINGLE_SHORT_NOT_OK)) {
|
||||
@ -689,9 +732,11 @@ static int
|
||||
ugen20_tr_open(struct libusb20_transfer *xfer, uint32_t MaxBufSize,
|
||||
uint32_t MaxFrameCount, uint8_t ep_no)
|
||||
{
|
||||
struct usb2_fs_open temp = { /* zero */ };
|
||||
struct usb2_fs_open temp;
|
||||
struct usb2_fs_endpoint *fsep;
|
||||
|
||||
memset(&temp, 0, sizeof(temp));
|
||||
|
||||
fsep = xfer->pdev->privBeData;
|
||||
fsep += xfer->trIndex;
|
||||
|
||||
@ -720,7 +765,9 @@ ugen20_tr_open(struct libusb20_transfer *xfer, uint32_t MaxBufSize,
|
||||
static int
|
||||
ugen20_tr_close(struct libusb20_transfer *xfer)
|
||||
{
|
||||
struct usb2_fs_close temp = { /* zero */ };
|
||||
struct usb2_fs_close temp;
|
||||
|
||||
memset(&temp, 0, sizeof(temp));
|
||||
|
||||
temp.ep_index = xfer->trIndex;
|
||||
|
||||
@ -733,7 +780,9 @@ ugen20_tr_close(struct libusb20_transfer *xfer)
|
||||
static int
|
||||
ugen20_tr_clear_stall_sync(struct libusb20_transfer *xfer)
|
||||
{
|
||||
struct usb2_fs_clear_stall_sync temp = { /* zero */ };
|
||||
struct usb2_fs_clear_stall_sync temp;
|
||||
|
||||
memset(&temp, 0, sizeof(temp));
|
||||
|
||||
/* if the transfer is active, an error will be returned */
|
||||
|
||||
@ -748,9 +797,11 @@ ugen20_tr_clear_stall_sync(struct libusb20_transfer *xfer)
|
||||
static void
|
||||
ugen20_tr_submit(struct libusb20_transfer *xfer)
|
||||
{
|
||||
struct usb2_fs_start temp = { /* zero */ };
|
||||
struct usb2_fs_start temp;
|
||||
struct usb2_fs_endpoint *fsep;
|
||||
|
||||
memset(&temp, 0, sizeof(temp));
|
||||
|
||||
fsep = xfer->pdev->privBeData;
|
||||
fsep += xfer->trIndex;
|
||||
|
||||
@ -781,7 +832,9 @@ ugen20_tr_submit(struct libusb20_transfer *xfer)
|
||||
static void
|
||||
ugen20_tr_cancel_async(struct libusb20_transfer *xfer)
|
||||
{
|
||||
struct usb2_fs_stop temp = { /* zero */ };
|
||||
struct usb2_fs_stop temp;
|
||||
|
||||
memset(&temp, 0, sizeof(temp));
|
||||
|
||||
temp.ep_index = xfer->trIndex;
|
||||
|
||||
@ -795,21 +848,21 @@ static int
|
||||
ugen20_be_ioctl(uint32_t cmd, void *data)
|
||||
{
|
||||
int f;
|
||||
int err;
|
||||
int error;
|
||||
|
||||
f = open("/dev/usb", O_RDONLY);
|
||||
if (f < 0)
|
||||
return (LIBUSB20_ERROR_OTHER);
|
||||
err = ioctl(f, cmd, data);
|
||||
if (err == -1) {
|
||||
error = ioctl(f, cmd, data);
|
||||
if (error == -1) {
|
||||
if (errno == EPERM) {
|
||||
err = LIBUSB20_ERROR_ACCESS;
|
||||
error = LIBUSB20_ERROR_ACCESS;
|
||||
} else {
|
||||
err = LIBUSB20_ERROR_OTHER;
|
||||
error = LIBUSB20_ERROR_OTHER;
|
||||
}
|
||||
}
|
||||
close(f);
|
||||
return (err);
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -817,16 +870,18 @@ ugen20_be_do_perm(uint32_t get_cmd, uint32_t set_cmd, uint8_t bus,
|
||||
uint8_t dev, uint8_t iface, uid_t *uid,
|
||||
gid_t *gid, mode_t *mode)
|
||||
{
|
||||
struct usb2_dev_perm perm = { /* zero */ };
|
||||
int err;
|
||||
struct usb2_dev_perm perm;
|
||||
int error;
|
||||
|
||||
memset(&perm, 0, sizeof(perm));
|
||||
|
||||
perm.bus_index = bus;
|
||||
perm.dev_index = dev;
|
||||
perm.iface_index = iface;
|
||||
|
||||
err = ugen20_be_ioctl(get_cmd, &perm);
|
||||
if (err)
|
||||
return (err);
|
||||
error = ugen20_be_ioctl(get_cmd, &perm);
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
if (set_cmd == 0) {
|
||||
if (uid)
|
||||
@ -934,18 +989,18 @@ ugen20_dev_set_iface_perm(struct libusb20_device *pdev,
|
||||
|
||||
static int
|
||||
ugen20_root_get_dev_quirk(struct libusb20_backend *pbe,
|
||||
uint16_t index, struct libusb20_quirk *pq)
|
||||
uint16_t quirk_index, struct libusb20_quirk *pq)
|
||||
{
|
||||
struct usb2_gen_quirk q;
|
||||
int err;
|
||||
int error;
|
||||
|
||||
memset(&q, 0, sizeof(q));
|
||||
|
||||
q.index = index;
|
||||
q.index = quirk_index;
|
||||
|
||||
err = ugen20_be_ioctl(USB_DEV_QUIRK_GET, &q);
|
||||
error = ugen20_be_ioctl(USB_DEV_QUIRK_GET, &q);
|
||||
|
||||
if (err) {
|
||||
if (error) {
|
||||
if (errno == EINVAL) {
|
||||
return (LIBUSB20_ERROR_NOT_FOUND);
|
||||
}
|
||||
@ -956,30 +1011,30 @@ ugen20_root_get_dev_quirk(struct libusb20_backend *pbe,
|
||||
pq->bcdDeviceHigh = q.bcdDeviceHigh;
|
||||
strlcpy(pq->quirkname, q.quirkname, sizeof(pq->quirkname));
|
||||
}
|
||||
return (err);
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
ugen20_root_get_quirk_name(struct libusb20_backend *pbe, uint16_t index,
|
||||
ugen20_root_get_quirk_name(struct libusb20_backend *pbe, uint16_t quirk_index,
|
||||
struct libusb20_quirk *pq)
|
||||
{
|
||||
struct usb2_gen_quirk q;
|
||||
int err;
|
||||
int error;
|
||||
|
||||
memset(&q, 0, sizeof(q));
|
||||
|
||||
q.index = index;
|
||||
q.index = quirk_index;
|
||||
|
||||
err = ugen20_be_ioctl(USB_QUIRK_NAME_GET, &q);
|
||||
error = ugen20_be_ioctl(USB_QUIRK_NAME_GET, &q);
|
||||
|
||||
if (err) {
|
||||
if (error) {
|
||||
if (errno == EINVAL) {
|
||||
return (LIBUSB20_ERROR_NOT_FOUND);
|
||||
}
|
||||
} else {
|
||||
strlcpy(pq->quirkname, q.quirkname, sizeof(pq->quirkname));
|
||||
}
|
||||
return (err);
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -987,7 +1042,7 @@ ugen20_root_add_dev_quirk(struct libusb20_backend *pbe,
|
||||
struct libusb20_quirk *pq)
|
||||
{
|
||||
struct usb2_gen_quirk q;
|
||||
int err;
|
||||
int error;
|
||||
|
||||
memset(&q, 0, sizeof(q));
|
||||
|
||||
@ -997,13 +1052,13 @@ ugen20_root_add_dev_quirk(struct libusb20_backend *pbe,
|
||||
q.bcdDeviceHigh = pq->bcdDeviceHigh;
|
||||
strlcpy(q.quirkname, pq->quirkname, sizeof(q.quirkname));
|
||||
|
||||
err = ugen20_be_ioctl(USB_DEV_QUIRK_ADD, &q);
|
||||
if (err) {
|
||||
error = ugen20_be_ioctl(USB_DEV_QUIRK_ADD, &q);
|
||||
if (error) {
|
||||
if (errno == ENOMEM) {
|
||||
return (LIBUSB20_ERROR_NO_MEM);
|
||||
}
|
||||
}
|
||||
return (err);
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -1011,7 +1066,7 @@ ugen20_root_remove_dev_quirk(struct libusb20_backend *pbe,
|
||||
struct libusb20_quirk *pq)
|
||||
{
|
||||
struct usb2_gen_quirk q;
|
||||
int err;
|
||||
int error;
|
||||
|
||||
memset(&q, 0, sizeof(q));
|
||||
|
||||
@ -1021,13 +1076,13 @@ ugen20_root_remove_dev_quirk(struct libusb20_backend *pbe,
|
||||
q.bcdDeviceHigh = pq->bcdDeviceHigh;
|
||||
strlcpy(q.quirkname, pq->quirkname, sizeof(q.quirkname));
|
||||
|
||||
err = ugen20_be_ioctl(USB_DEV_QUIRK_REMOVE, &q);
|
||||
if (err) {
|
||||
error = ugen20_be_ioctl(USB_DEV_QUIRK_REMOVE, &q);
|
||||
if (error) {
|
||||
if (errno == EINVAL) {
|
||||
return (LIBUSB20_ERROR_NOT_FOUND);
|
||||
}
|
||||
}
|
||||
return (err);
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -232,6 +232,8 @@ see
|
||||
.Xr ppbus 4
|
||||
.It Pa usb/
|
||||
The USB subsystem
|
||||
.It Pa usb2/include
|
||||
The USB subsystem
|
||||
.It Pa utopia/
|
||||
Physical chip driver for ATM interfaces;
|
||||
see
|
||||
|
@ -148,6 +148,7 @@ LIBUFS?= ${DESTDIR}${LIBDIR}/libufs.a
|
||||
LIBUGIDFW?= ${DESTDIR}${LIBDIR}/libugidfw.a
|
||||
LIBUMEM?= ${DESTDIR}${LIBDIR}/libumem.a
|
||||
LIBUSBHID?= ${DESTDIR}${LIBDIR}/libusbhid.a
|
||||
LIBUSB20?= ${DESTDIR}${LIBDIR}/libusb20.a
|
||||
LIBUTIL?= ${DESTDIR}${LIBDIR}/libutil.a
|
||||
LIBUUTIL?= ${DESTDIR}${LIBDIR}/libuutil.a
|
||||
LIBVGL?= ${DESTDIR}${LIBDIR}/libvgl.a
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
struct RioCommand
|
||||
{
|
||||
u_int16_t length;
|
||||
uint16_t length;
|
||||
int request;
|
||||
int requesttype;
|
||||
int value;
|
||||
|
@ -365,6 +365,7 @@ static const struct usb2_config
|
||||
DRIVER_MODULE(ng_ubt, ushub, ubt_driver, ubt_devclass, ubt_modevent, 0);
|
||||
MODULE_VERSION(ng_ubt, NG_BLUETOOTH_VERSION);
|
||||
MODULE_DEPEND(ng_ubt, netgraph, NG_ABI_VERSION, NG_ABI_VERSION, NG_ABI_VERSION);
|
||||
MODULE_DEPEND(ng_ubt, ng_hci, NG_BLUETOOTH_VERSION, NG_BLUETOOTH_VERSION, NG_BLUETOOTH_VERSION);
|
||||
MODULE_DEPEND(ng_ubt, usb2_bluetooth, 1, 1, 1);
|
||||
MODULE_DEPEND(ng_ubt, usb2_core, 1, 1, 1);
|
||||
|
||||
|
@ -183,6 +183,8 @@ ehci_hc_reset(ehci_softc_t *sc)
|
||||
usb2_pause_mtx(&sc->sc_bus.bus_mtx, 1);
|
||||
hcr = EOREAD4(sc, EHCI_USBCMD);
|
||||
if (!(hcr & EHCI_CMD_HCRESET)) {
|
||||
if (sc->sc_flags & EHCI_SCFLG_SETMODE)
|
||||
EOWRITE4(sc, 0x68, 0x3);
|
||||
hcr = 0;
|
||||
break;
|
||||
}
|
||||
@ -3301,7 +3303,16 @@ ehci_root_ctrl_done(struct usb2_xfer *xfer,
|
||||
}
|
||||
v = EOREAD4(sc, EHCI_PORTSC(index));
|
||||
DPRINTFN(9, "port status=0x%04x\n", v);
|
||||
i = UPS_HIGH_SPEED;
|
||||
if (sc->sc_flags & EHCI_SCFLG_FORCESPEED) {
|
||||
if ((v & 0xc000000) == 0x8000000)
|
||||
i = UPS_HIGH_SPEED;
|
||||
else if ((v & 0xc000000) == 0x4000000)
|
||||
i = UPS_LOW_SPEED;
|
||||
else
|
||||
i = 0;
|
||||
} else {
|
||||
i = UPS_HIGH_SPEED;
|
||||
}
|
||||
if (v & EHCI_PS_CS)
|
||||
i |= UPS_CURRENT_CONNECT_STATUS;
|
||||
if (v & EHCI_PS_PE)
|
||||
@ -3378,7 +3389,8 @@ ehci_root_ctrl_done(struct usb2_xfer *xfer,
|
||||
}
|
||||
|
||||
/* Terminate reset sequence. */
|
||||
EOWRITE4(sc, port, v);
|
||||
if (!(sc->sc_flags & EHCI_SCFLG_NORESTERM))
|
||||
EOWRITE4(sc, port, v);
|
||||
|
||||
if (use_polling) {
|
||||
/* polling */
|
||||
|
@ -468,6 +468,12 @@ typedef struct ehci_softc {
|
||||
|
||||
uint16_t sc_intr_stat[EHCI_VIRTUAL_FRAMELIST_COUNT];
|
||||
uint16_t sc_id_vendor; /* vendor ID for root hub */
|
||||
uint16_t sc_flags; /* chip specific flags */
|
||||
#define EHCI_SCFLG_SETMODE 0x0001 /* set bridge mode again after init
|
||||
* (Marvell) */
|
||||
#define EHCI_SCFLG_FORCESPEED 0x0002 /* force speed (Marvell) */
|
||||
#define EHCI_SCFLG_NORESTERM 0x0004 /* don't terminate reset sequence
|
||||
* (Marvell) */
|
||||
|
||||
uint8_t sc_offs; /* offset to operational registers */
|
||||
uint8_t sc_doorbell_disable; /* set on doorbell failure */
|
||||
|
@ -1,266 +0,0 @@
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2008 Hans Petter Selasky <hselasky@freebsd.org>
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <dev/usb2/include/usb2_mfunc.h>
|
||||
#include <dev/usb2/include/usb2_defs.h>
|
||||
#include <dev/usb2/include/usb2_standard.h>
|
||||
|
||||
#include <dev/usb2/core/usb2_core.h>
|
||||
#include <dev/usb2/core/usb2_busdma.h>
|
||||
#include <dev/usb2/core/usb2_process.h>
|
||||
#include <dev/usb2/core/usb2_config_td.h>
|
||||
#include <dev/usb2/core/usb2_sw_transfer.h>
|
||||
#include <dev/usb2/core/usb2_util.h>
|
||||
|
||||
#include <dev/usb2/controller/usb2_controller.h>
|
||||
#include <dev/usb2/controller/usb2_bus.h>
|
||||
#include <dev/usb2/controller/uss820dci.h>
|
||||
|
||||
#include <dev/pccard/pccardreg.h>
|
||||
#include <dev/pccard/pccardvar.h>
|
||||
|
||||
#include <sys/rman.h>
|
||||
|
||||
static device_probe_t uss820_pccard_probe;
|
||||
static device_attach_t uss820_pccard_attach;
|
||||
static device_detach_t uss820_pccard_detach;
|
||||
static device_suspend_t uss820_pccard_suspend;
|
||||
static device_resume_t uss820_pccard_resume;
|
||||
static device_shutdown_t uss820_pccard_shutdown;
|
||||
|
||||
static uint8_t uss820_pccard_lookup(device_t dev);
|
||||
|
||||
static device_method_t uss820dci_methods[] = {
|
||||
/* Device interface */
|
||||
DEVMETHOD(device_probe, uss820_pccard_probe),
|
||||
DEVMETHOD(device_attach, uss820_pccard_attach),
|
||||
DEVMETHOD(device_detach, uss820_pccard_detach),
|
||||
DEVMETHOD(device_suspend, uss820_pccard_suspend),
|
||||
DEVMETHOD(device_resume, uss820_pccard_resume),
|
||||
DEVMETHOD(device_shutdown, uss820_pccard_shutdown),
|
||||
|
||||
/* Bus interface */
|
||||
DEVMETHOD(bus_print_child, bus_generic_print_child),
|
||||
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
static driver_t uss820dci_driver = {
|
||||
.name = "uss820",
|
||||
.methods = uss820dci_methods,
|
||||
.size = sizeof(struct uss820dci_softc),
|
||||
};
|
||||
|
||||
static devclass_t uss820dci_devclass;
|
||||
|
||||
DRIVER_MODULE(uss820, pccard, uss820dci_driver, uss820dci_devclass, 0, 0);
|
||||
MODULE_DEPEND(uss820, usb2_core, 1, 1, 1);
|
||||
|
||||
static const char *const uss820_desc = "USS820 USB Device Controller";
|
||||
|
||||
static int
|
||||
uss820_pccard_suspend(device_t dev)
|
||||
{
|
||||
struct uss820dci_softc *sc = device_get_softc(dev);
|
||||
int err;
|
||||
|
||||
err = bus_generic_suspend(dev);
|
||||
if (err == 0) {
|
||||
uss820dci_suspend(sc);
|
||||
}
|
||||
return (err);
|
||||
}
|
||||
|
||||
static int
|
||||
uss820_pccard_resume(device_t dev)
|
||||
{
|
||||
struct uss820dci_softc *sc = device_get_softc(dev);
|
||||
int err;
|
||||
|
||||
uss820dci_resume(sc);
|
||||
|
||||
err = bus_generic_resume(dev);
|
||||
|
||||
return (err);
|
||||
}
|
||||
|
||||
static int
|
||||
uss820_pccard_shutdown(device_t dev)
|
||||
{
|
||||
struct uss820dci_softc *sc = device_get_softc(dev);
|
||||
int err;
|
||||
|
||||
err = bus_generic_shutdown(dev);
|
||||
if (err)
|
||||
return (err);
|
||||
|
||||
uss820dci_uninit(sc);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
uss820_pccard_lookup(device_t dev)
|
||||
{
|
||||
uint32_t prod;
|
||||
uint32_t vend;
|
||||
|
||||
pccard_get_vendor(dev, &vend);
|
||||
pccard_get_product(dev, &prod);
|
||||
|
||||
/* ID's will be added later */
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
uss820_pccard_probe(device_t dev)
|
||||
{
|
||||
if (uss820_pccard_lookup(dev)) {
|
||||
device_set_desc(dev, uss820_desc);
|
||||
return (0);
|
||||
}
|
||||
return (ENXIO);
|
||||
}
|
||||
static int
|
||||
uss820_pccard_attach(device_t dev)
|
||||
{
|
||||
struct uss820dci_softc *sc = device_get_softc(dev);
|
||||
int err;
|
||||
int rid;
|
||||
|
||||
if (sc == NULL) {
|
||||
return (ENXIO);
|
||||
}
|
||||
/* get all DMA memory */
|
||||
|
||||
if (usb2_bus_mem_alloc_all(&sc->sc_bus,
|
||||
USB_GET_DMA_TAG(dev), NULL)) {
|
||||
return (ENOMEM);
|
||||
}
|
||||
rid = 0;
|
||||
sc->sc_io_res =
|
||||
bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, RF_ACTIVE);
|
||||
|
||||
if (!sc->sc_io_res) {
|
||||
goto error;
|
||||
}
|
||||
sc->sc_io_tag = rman_get_bustag(sc->sc_io_res);
|
||||
sc->sc_io_hdl = rman_get_bushandle(sc->sc_io_res);
|
||||
sc->sc_io_size = rman_get_size(sc->sc_io_res);
|
||||
|
||||
/* multiply all addresses by 4 */
|
||||
sc->sc_reg_shift = 2;
|
||||
|
||||
rid = 0;
|
||||
sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
|
||||
RF_SHAREABLE | RF_ACTIVE);
|
||||
if (sc->sc_irq_res == NULL) {
|
||||
goto error;
|
||||
}
|
||||
sc->sc_bus.bdev = device_add_child(dev, "usbus", -1);
|
||||
if (!(sc->sc_bus.bdev)) {
|
||||
goto error;
|
||||
}
|
||||
device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);
|
||||
|
||||
err = usb2_config_td_setup(&sc->sc_config_td, sc,
|
||||
&sc->sc_bus.bus_mtx, NULL, 0, 4);
|
||||
if (err) {
|
||||
device_printf(dev, "could not setup config thread!\n");
|
||||
goto error;
|
||||
}
|
||||
#if (__FreeBSD_version >= 700031)
|
||||
err = bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
|
||||
NULL, (void *)uss820dci_interrupt, sc, &sc->sc_intr_hdl);
|
||||
#else
|
||||
err = bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
|
||||
(void *)uss820dci_interrupt, sc, &sc->sc_intr_hdl);
|
||||
#endif
|
||||
if (err) {
|
||||
sc->sc_intr_hdl = NULL;
|
||||
goto error;
|
||||
}
|
||||
err = uss820dci_init(sc);
|
||||
if (err) {
|
||||
device_printf(dev, "Init failed\n");
|
||||
goto error;
|
||||
}
|
||||
err = device_probe_and_attach(sc->sc_bus.bdev);
|
||||
if (err) {
|
||||
device_printf(dev, "USB probe and attach failed\n");
|
||||
goto error;
|
||||
}
|
||||
return (0);
|
||||
|
||||
error:
|
||||
uss820_pccard_detach(dev);
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
static int
|
||||
uss820_pccard_detach(device_t dev)
|
||||
{
|
||||
struct uss820dci_softc *sc = device_get_softc(dev);
|
||||
device_t bdev;
|
||||
int err;
|
||||
|
||||
if (sc->sc_bus.bdev) {
|
||||
bdev = sc->sc_bus.bdev;
|
||||
device_detach(bdev);
|
||||
device_delete_child(dev, bdev);
|
||||
}
|
||||
/* during module unload there are lots of children leftover */
|
||||
device_delete_all_children(dev);
|
||||
|
||||
if (sc->sc_irq_res && sc->sc_intr_hdl) {
|
||||
/*
|
||||
* only call at91_udp_uninit() after at91_udp_init()
|
||||
*/
|
||||
uss820dci_uninit(sc);
|
||||
|
||||
err = bus_teardown_intr(dev, sc->sc_irq_res,
|
||||
sc->sc_intr_hdl);
|
||||
sc->sc_intr_hdl = NULL;
|
||||
}
|
||||
if (sc->sc_irq_res) {
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0,
|
||||
sc->sc_irq_res);
|
||||
sc->sc_irq_res = NULL;
|
||||
}
|
||||
if (sc->sc_io_res) {
|
||||
bus_release_resource(dev, SYS_RES_IOPORT, 0,
|
||||
sc->sc_io_res);
|
||||
sc->sc_io_res = NULL;
|
||||
}
|
||||
usb2_config_td_unsetup(&sc->sc_config_td);
|
||||
|
||||
usb2_bus_mem_free_all(&sc->sc_bus, NULL);
|
||||
|
||||
return (0);
|
||||
}
|
@ -601,6 +601,12 @@ usb2_pc_load_mem(struct usb2_page_cache *pc, uint32_t size, uint8_t sync)
|
||||
|
||||
uptag = pc->tag_parent;
|
||||
|
||||
/*
|
||||
* We have to unload the previous loaded DMA
|
||||
* pages before trying to load a new one!
|
||||
*/
|
||||
bus_dmamap_unload(pc->tag, pc->map);
|
||||
|
||||
/*
|
||||
* Try to load memory into DMA.
|
||||
*/
|
||||
@ -616,6 +622,12 @@ usb2_pc_load_mem(struct usb2_page_cache *pc, uint32_t size, uint8_t sync)
|
||||
}
|
||||
} else {
|
||||
|
||||
/*
|
||||
* We have to unload the previous loaded DMA
|
||||
* pages before trying to load a new one!
|
||||
*/
|
||||
bus_dmamap_unload(pc->tag, pc->map);
|
||||
|
||||
/*
|
||||
* Try to load memory into DMA. The callback
|
||||
* will be called in all cases:
|
||||
@ -644,6 +656,10 @@ usb2_pc_load_mem(struct usb2_page_cache *pc, uint32_t size, uint8_t sync)
|
||||
void
|
||||
usb2_pc_cpu_invalidate(struct usb2_page_cache *pc)
|
||||
{
|
||||
if (pc->page_offset_end == pc->page_offset_buf) {
|
||||
/* nothing has been loaded into this page cache! */
|
||||
return;
|
||||
}
|
||||
bus_dmamap_sync(pc->tag, pc->map,
|
||||
BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
|
||||
return;
|
||||
@ -655,6 +671,10 @@ usb2_pc_cpu_invalidate(struct usb2_page_cache *pc)
|
||||
void
|
||||
usb2_pc_cpu_flush(struct usb2_page_cache *pc)
|
||||
{
|
||||
if (pc->page_offset_end == pc->page_offset_buf) {
|
||||
/* nothing has been loaded into this page cache! */
|
||||
return;
|
||||
}
|
||||
bus_dmamap_sync(pc->tag, pc->map,
|
||||
BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
|
||||
return;
|
||||
@ -958,6 +978,12 @@ usb2_pc_load_mem(struct usb2_page_cache *pc, uint32_t size, uint8_t sync)
|
||||
|
||||
if (size > 0) {
|
||||
|
||||
/*
|
||||
* We have to unload the previous loaded DMA
|
||||
* pages before trying to load a new one!
|
||||
*/
|
||||
bus_dmamap_unload(pc->tag, pc->map);
|
||||
|
||||
/* try to load memory into DMA using using no wait option */
|
||||
if (bus_dmamap_load(pc->tag, pc->map, pc->buffer,
|
||||
size, NULL, BUS_DMA_NOWAIT)) {
|
||||
@ -995,6 +1021,10 @@ usb2_pc_cpu_invalidate(struct usb2_page_cache *pc)
|
||||
|
||||
len = pc->page_offset_end - pc->page_offset_buf;
|
||||
|
||||
if (len == 0) {
|
||||
/* nothing has been loaded into this page cache */
|
||||
return;
|
||||
}
|
||||
bus_dmamap_sync(pc->tag, pc->map, 0, len,
|
||||
BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
|
||||
return;
|
||||
@ -1010,6 +1040,10 @@ usb2_pc_cpu_flush(struct usb2_page_cache *pc)
|
||||
|
||||
len = pc->page_offset_end - pc->page_offset_buf;
|
||||
|
||||
if (len == 0) {
|
||||
/* nothing has been loaded into this page cache */
|
||||
return;
|
||||
}
|
||||
bus_dmamap_sync(pc->tag, pc->map, 0, len,
|
||||
BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
|
||||
return;
|
||||
@ -1358,12 +1392,10 @@ usb2_bdma_pre_sync(struct usb2_xfer *xfer)
|
||||
|
||||
while (nframes--) {
|
||||
|
||||
if (pc->page_offset_buf != pc->page_offset_end) {
|
||||
if (pc->isread) {
|
||||
usb2_pc_cpu_invalidate(pc);
|
||||
} else {
|
||||
usb2_pc_cpu_flush(pc);
|
||||
}
|
||||
if (pc->isread) {
|
||||
usb2_pc_cpu_invalidate(pc);
|
||||
} else {
|
||||
usb2_pc_cpu_flush(pc);
|
||||
}
|
||||
pc++;
|
||||
}
|
||||
@ -1394,11 +1426,8 @@ usb2_bdma_post_sync(struct usb2_xfer *xfer)
|
||||
pc = xfer->frbuffers;
|
||||
|
||||
while (nframes--) {
|
||||
|
||||
if (pc->page_offset_buf != pc->page_offset_end) {
|
||||
if (pc->isread) {
|
||||
usb2_pc_cpu_invalidate(pc);
|
||||
}
|
||||
if (pc->isread) {
|
||||
usb2_pc_cpu_invalidate(pc);
|
||||
}
|
||||
pc++;
|
||||
}
|
||||
|
@ -159,12 +159,12 @@
|
||||
#define usb2_callout_drain(c) callout_drain(&(c)->co)
|
||||
#define usb2_callout_pending(c) callout_pending(&(c)->co)
|
||||
|
||||
#define USB_BUS_LOCK(_b) mtx_lock(&(_b)->bus_mtx)
|
||||
#define USB_BUS_UNLOCK(_b) mtx_unlock(&(_b)->bus_mtx)
|
||||
#define USB_BUS_LOCK_ASSERT(_b, _t) mtx_assert(&(_b)->bus_mtx, _t)
|
||||
#define USB_XFER_LOCK(_x) mtx_lock((_x)->xfer_mtx)
|
||||
#define USB_XFER_UNLOCK(_x) mtx_unlock((_x)->xfer_mtx)
|
||||
#define USB_XFER_LOCK_ASSERT(_x, _t) mtx_assert((_x)->xfer_mtx, _t)
|
||||
#define USB_BUS_LOCK(_b) mtx_lock(&(_b)->bus_mtx)
|
||||
#define USB_BUS_UNLOCK(_b) mtx_unlock(&(_b)->bus_mtx)
|
||||
#define USB_BUS_LOCK_ASSERT(_b, _t) mtx_assert(&(_b)->bus_mtx, _t)
|
||||
#define USB_XFER_LOCK(_x) mtx_lock((_x)->xfer_mtx)
|
||||
#define USB_XFER_UNLOCK(_x) mtx_unlock((_x)->xfer_mtx)
|
||||
#define USB_XFER_LOCK_ASSERT(_x, _t) mtx_assert((_x)->xfer_mtx, _t)
|
||||
/* structure prototypes */
|
||||
|
||||
struct file;
|
||||
@ -401,13 +401,14 @@ struct usb2_location {
|
||||
struct usb2_fifo *rxfifo;
|
||||
struct usb2_fifo *txfifo;
|
||||
uint32_t devloc; /* original devloc */
|
||||
uint16_t bus_index;
|
||||
uint8_t dev_index;
|
||||
uint8_t iface_index;
|
||||
uint8_t ep_index;
|
||||
uint8_t is_read;
|
||||
uint8_t is_write;
|
||||
uint8_t is_uref;
|
||||
uint16_t bus_index; /* bus index */
|
||||
uint8_t dev_index; /* device index */
|
||||
uint8_t iface_index; /* interface index */
|
||||
uint8_t fifo_index; /* FIFO index */
|
||||
uint8_t is_read; /* set if location has read access */
|
||||
uint8_t is_write; /* set if location has write access */
|
||||
uint8_t is_uref; /* set if USB refcount decr. needed */
|
||||
uint8_t is_usbfs; /* set if USB-FS is active */
|
||||
};
|
||||
|
||||
/* external variables */
|
||||
|
@ -464,21 +464,16 @@ usb2_ref_device(struct file *fp, struct usb2_location *ploc, uint32_t devloc)
|
||||
struct usb2_fifo **ppf;
|
||||
struct usb2_fifo *f;
|
||||
int fflags;
|
||||
uint8_t need_uref;
|
||||
uint8_t dev_ep_index;
|
||||
|
||||
if (fp) {
|
||||
/* check if we need uref hint */
|
||||
need_uref = devloc ? 0 : 1;
|
||||
/* check if we need uref */
|
||||
ploc->is_uref = devloc ? 0 : 1;
|
||||
/* get devloc - already verified */
|
||||
devloc = USB_P2U(fp->f_data);
|
||||
/* get file flags */
|
||||
fflags = fp->f_flag;
|
||||
/* only ref FIFO */
|
||||
ploc->is_uref = 0;
|
||||
/* devloc should be valid */
|
||||
} else {
|
||||
/* we need uref */
|
||||
need_uref = 1;
|
||||
/* only ref device */
|
||||
fflags = 0;
|
||||
/* search for FIFO */
|
||||
@ -496,7 +491,7 @@ usb2_ref_device(struct file *fp, struct usb2_location *ploc, uint32_t devloc)
|
||||
ploc->dev_index = (devloc / USB_BUS_MAX) % USB_DEV_MAX;
|
||||
ploc->iface_index = (devloc / (USB_BUS_MAX *
|
||||
USB_DEV_MAX)) % USB_IFACE_MAX;
|
||||
ploc->ep_index = (devloc / (USB_BUS_MAX * USB_DEV_MAX *
|
||||
ploc->fifo_index = (devloc / (USB_BUS_MAX * USB_DEV_MAX *
|
||||
USB_IFACE_MAX));
|
||||
|
||||
mtx_lock(&usb2_ref_lock);
|
||||
@ -518,8 +513,75 @@ usb2_ref_device(struct file *fp, struct usb2_location *ploc, uint32_t devloc)
|
||||
DPRINTFN(2, "no dev ref\n");
|
||||
goto error;
|
||||
}
|
||||
/* check if we are doing an open */
|
||||
if (fp == NULL) {
|
||||
/* set defaults */
|
||||
ploc->txfifo = NULL;
|
||||
ploc->rxfifo = NULL;
|
||||
ploc->is_write = 0;
|
||||
ploc->is_read = 0;
|
||||
ploc->is_usbfs = 0;
|
||||
/* NOTE: variable overloading: */
|
||||
dev_ep_index = ploc->fifo_index;
|
||||
} else {
|
||||
/* initialise "is_usbfs" flag */
|
||||
ploc->is_usbfs = 0;
|
||||
dev_ep_index = 255; /* dummy */
|
||||
|
||||
/* check for write */
|
||||
if (fflags & FWRITE) {
|
||||
ppf = ploc->udev->fifo;
|
||||
f = ppf[ploc->fifo_index + USB_FIFO_TX];
|
||||
ploc->txfifo = f;
|
||||
ploc->is_write = 1; /* ref */
|
||||
if ((f == NULL) ||
|
||||
(f->refcount == USB_FIFO_REF_MAX) ||
|
||||
(f->curr_file != fp)) {
|
||||
goto error;
|
||||
}
|
||||
/* check if USB-FS is active */
|
||||
if (f->fs_ep_max != 0) {
|
||||
ploc->is_usbfs = 1;
|
||||
}
|
||||
/*
|
||||
* Get real endpoint index associated with
|
||||
* this FIFO:
|
||||
*/
|
||||
dev_ep_index = f->dev_ep_index;
|
||||
} else {
|
||||
ploc->txfifo = NULL;
|
||||
ploc->is_write = 0; /* no ref */
|
||||
}
|
||||
|
||||
/* check for read */
|
||||
if (fflags & FREAD) {
|
||||
ppf = ploc->udev->fifo;
|
||||
f = ppf[ploc->fifo_index + USB_FIFO_RX];
|
||||
ploc->rxfifo = f;
|
||||
ploc->is_read = 1; /* ref */
|
||||
if ((f == NULL) ||
|
||||
(f->refcount == USB_FIFO_REF_MAX) ||
|
||||
(f->curr_file != fp)) {
|
||||
goto error;
|
||||
}
|
||||
/* check if USB-FS is active */
|
||||
if (f->fs_ep_max != 0) {
|
||||
ploc->is_usbfs = 1;
|
||||
}
|
||||
/*
|
||||
* Get real endpoint index associated with
|
||||
* this FIFO:
|
||||
*/
|
||||
dev_ep_index = f->dev_ep_index;
|
||||
} else {
|
||||
ploc->rxfifo = NULL;
|
||||
ploc->is_read = 0; /* no ref */
|
||||
}
|
||||
}
|
||||
|
||||
/* check if we require an interface */
|
||||
ploc->iface = usb2_get_iface(ploc->udev, ploc->iface_index);
|
||||
if (ploc->ep_index != 0) {
|
||||
if (dev_ep_index != 0) {
|
||||
/* non control endpoint - we need an interface */
|
||||
if (ploc->iface == NULL) {
|
||||
DPRINTFN(2, "no iface\n");
|
||||
@ -530,72 +592,18 @@ usb2_ref_device(struct file *fp, struct usb2_location *ploc, uint32_t devloc)
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
/* check if we are doing an open */
|
||||
if (fp == NULL) {
|
||||
/* set defaults */
|
||||
ploc->txfifo = NULL;
|
||||
ploc->rxfifo = NULL;
|
||||
ploc->is_write = 0;
|
||||
ploc->is_read = 0;
|
||||
} else {
|
||||
/* check for write */
|
||||
if (fflags & FWRITE) {
|
||||
ppf = ploc->udev->fifo;
|
||||
f = ppf[ploc->ep_index + USB_FIFO_TX];
|
||||
ploc->txfifo = f;
|
||||
ploc->is_write = 1; /* ref */
|
||||
if ((f == NULL) ||
|
||||
(f->refcount == USB_FIFO_REF_MAX) ||
|
||||
(f->curr_file != fp)) {
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
ploc->txfifo = NULL;
|
||||
ploc->is_write = 0; /* no ref */
|
||||
}
|
||||
|
||||
/* check for read */
|
||||
if (fflags & FREAD) {
|
||||
ppf = ploc->udev->fifo;
|
||||
f = ppf[ploc->ep_index + USB_FIFO_RX];
|
||||
ploc->rxfifo = f;
|
||||
ploc->is_read = 1; /* ref */
|
||||
if ((f == NULL) ||
|
||||
(f->refcount == USB_FIFO_REF_MAX) ||
|
||||
(f->curr_file != fp)) {
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
ploc->rxfifo = NULL;
|
||||
ploc->is_read = 0; /* no ref */
|
||||
}
|
||||
}
|
||||
|
||||
/* when everything is OK we increment the refcounts */
|
||||
if (ploc->is_write) {
|
||||
DPRINTFN(2, "ref write\n");
|
||||
ploc->txfifo->refcount++;
|
||||
if (ploc->txfifo->flag_no_uref == 0) {
|
||||
/* we need extra locking */
|
||||
ploc->is_uref = 1;
|
||||
}
|
||||
}
|
||||
if (ploc->is_read) {
|
||||
DPRINTFN(2, "ref read\n");
|
||||
ploc->rxfifo->refcount++;
|
||||
if (ploc->rxfifo->flag_no_uref == 0) {
|
||||
/* we need extra locking */
|
||||
ploc->is_uref = 1;
|
||||
}
|
||||
}
|
||||
if (ploc->is_uref) {
|
||||
if (need_uref) {
|
||||
DPRINTFN(2, "ref udev - needed\n");
|
||||
ploc->udev->refcount++;
|
||||
} else {
|
||||
DPRINTFN(2, "ref udev - not needed\n");
|
||||
ploc->is_uref = 0;
|
||||
}
|
||||
DPRINTFN(2, "ref udev - needed\n");
|
||||
ploc->udev->refcount++;
|
||||
}
|
||||
mtx_unlock(&usb2_ref_lock);
|
||||
|
||||
@ -615,6 +623,59 @@ usb2_ref_device(struct file *fp, struct usb2_location *ploc, uint32_t devloc)
|
||||
return (USB_ERR_INVAL);
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*
|
||||
* usb2_uref_location
|
||||
*
|
||||
* This function is used to upgrade an USB reference to include the
|
||||
* USB device reference on a USB location.
|
||||
*
|
||||
* Return values:
|
||||
* 0: Success, refcount incremented on the given USB device.
|
||||
* Else: Failure.
|
||||
*------------------------------------------------------------------------*/
|
||||
static usb2_error_t
|
||||
usb2_uref_location(struct usb2_location *ploc)
|
||||
{
|
||||
/*
|
||||
* Check if we already got an USB reference on this location:
|
||||
*/
|
||||
if (ploc->is_uref) {
|
||||
return (0); /* success */
|
||||
}
|
||||
mtx_lock(&usb2_ref_lock);
|
||||
if (ploc->bus != devclass_get_softc(usb2_devclass_ptr, ploc->bus_index)) {
|
||||
DPRINTFN(2, "bus changed at %u\n", ploc->bus_index);
|
||||
goto error;
|
||||
}
|
||||
if (ploc->udev != ploc->bus->devices[ploc->dev_index]) {
|
||||
DPRINTFN(2, "device changed at %u\n", ploc->dev_index);
|
||||
goto error;
|
||||
}
|
||||
if (ploc->udev->refcount == USB_DEV_REF_MAX) {
|
||||
DPRINTFN(2, "no dev ref\n");
|
||||
goto error;
|
||||
}
|
||||
DPRINTFN(2, "ref udev\n");
|
||||
ploc->udev->refcount++;
|
||||
mtx_unlock(&usb2_ref_lock);
|
||||
|
||||
/* set "uref" */
|
||||
ploc->is_uref = 1;
|
||||
|
||||
/*
|
||||
* We are about to alter the bus-state. Apply the
|
||||
* required locks.
|
||||
*/
|
||||
sx_xlock(ploc->udev->default_sx + 1);
|
||||
mtx_lock(&Giant); /* XXX */
|
||||
return (0);
|
||||
|
||||
error:
|
||||
mtx_unlock(&usb2_ref_lock);
|
||||
DPRINTFN(2, "fail\n");
|
||||
return (USB_ERR_INVAL);
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*
|
||||
* usb2_unref_device
|
||||
*
|
||||
@ -672,7 +733,9 @@ usb2_fifo_create(struct usb2_location *ploc, uint32_t *pdevloc, int fflags)
|
||||
struct usb2_fifo *f;
|
||||
struct usb2_pipe *pipe;
|
||||
uint8_t iface_index = ploc->iface_index;
|
||||
uint8_t dev_ep_index = ploc->ep_index;
|
||||
|
||||
/* NOTE: variable overloading: */
|
||||
uint8_t dev_ep_index = ploc->fifo_index;
|
||||
uint8_t n;
|
||||
uint8_t is_tx;
|
||||
uint8_t is_rx;
|
||||
@ -770,9 +833,6 @@ usb2_fifo_create(struct usb2_location *ploc, uint32_t *pdevloc, int fflags)
|
||||
f->methods = &usb2_ugen_methods;
|
||||
f->iface_index = iface_index;
|
||||
f->udev = udev;
|
||||
if (dev_ep_index != 0) {
|
||||
f->flag_no_uref = 1;
|
||||
}
|
||||
mtx_lock(&usb2_ref_lock);
|
||||
udev->fifo[n + USB_FIFO_TX] = f;
|
||||
mtx_unlock(&usb2_ref_lock);
|
||||
@ -798,9 +858,6 @@ usb2_fifo_create(struct usb2_location *ploc, uint32_t *pdevloc, int fflags)
|
||||
f->methods = &usb2_ugen_methods;
|
||||
f->iface_index = iface_index;
|
||||
f->udev = udev;
|
||||
if (dev_ep_index != 0) {
|
||||
f->flag_no_uref = 1;
|
||||
}
|
||||
mtx_lock(&usb2_ref_lock);
|
||||
udev->fifo[n + USB_FIFO_RX] = f;
|
||||
mtx_unlock(&usb2_ref_lock);
|
||||
@ -1113,15 +1170,23 @@ usb2_check_thread_perm(struct usb2_device *udev, struct thread *td,
|
||||
struct usb2_interface *iface;
|
||||
int err;
|
||||
|
||||
iface = usb2_get_iface(udev, iface_index);
|
||||
if (iface == NULL) {
|
||||
return (EINVAL);
|
||||
}
|
||||
if (iface->idesc == NULL) {
|
||||
return (EINVAL);
|
||||
if (ep_index != 0) {
|
||||
/*
|
||||
* Non-control endpoints are always
|
||||
* associated with an interface:
|
||||
*/
|
||||
iface = usb2_get_iface(udev, iface_index);
|
||||
if (iface == NULL) {
|
||||
return (EINVAL);
|
||||
}
|
||||
if (iface->idesc == NULL) {
|
||||
return (EINVAL);
|
||||
}
|
||||
} else {
|
||||
iface = NULL;
|
||||
}
|
||||
/* scan down the permissions tree */
|
||||
if ((ep_index != 0) && iface &&
|
||||
if ((iface != NULL) &&
|
||||
(usb2_check_access(fflags, &iface->perm) == 0)) {
|
||||
/* we got access through the interface */
|
||||
err = 0;
|
||||
@ -1198,8 +1263,14 @@ usb2_fdopen(struct cdev *dev, int xxx_oflags, struct thread *td,
|
||||
DPRINTFN(2, "cannot ref device\n");
|
||||
return (ENXIO);
|
||||
}
|
||||
/*
|
||||
* NOTE: Variable overloading. "usb2_fifo_create" will update
|
||||
* the FIFO index. Right here we can assume that the
|
||||
* "fifo_index" is the same like the endpoint number without
|
||||
* direction mask, if the "fifo_index" is less than 16.
|
||||
*/
|
||||
err = usb2_check_thread_perm(loc.udev, td, fflags,
|
||||
loc.iface_index, loc.ep_index);
|
||||
loc.iface_index, loc.fifo_index);
|
||||
|
||||
/* check for error */
|
||||
if (err) {
|
||||
@ -1447,7 +1518,7 @@ usb2_close_f(struct file *fp, struct thread *td)
|
||||
|
||||
DPRINTFN(2, "fflags=%u\n", fflags);
|
||||
|
||||
err = usb2_ref_device(fp, &loc, 0);;
|
||||
err = usb2_ref_device(fp, &loc, 0 /* need uref */ );;
|
||||
|
||||
/* restore some file variables */
|
||||
fp->f_ops = usb2_old_f_ops;
|
||||
@ -1512,7 +1583,7 @@ usb2_ioctl_f_sub(struct usb2_fifo *f, u_long cmd, void *addr,
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return (ENOTTY);
|
||||
return (ENOIOCTL);
|
||||
}
|
||||
return (error);
|
||||
}
|
||||
@ -1522,13 +1593,11 @@ usb2_ioctl_f(struct file *fp, u_long cmd, void *addr,
|
||||
struct ucred *cred, struct thread *td)
|
||||
{
|
||||
struct usb2_location loc;
|
||||
struct usb2_fifo *f;
|
||||
int fflags;
|
||||
int err_rx;
|
||||
int err_tx;
|
||||
int err;
|
||||
uint8_t is_common = 0;
|
||||
|
||||
err = usb2_ref_device(fp, &loc, 0);;
|
||||
err = usb2_ref_device(fp, &loc, 1 /* no uref */ );;
|
||||
if (err) {
|
||||
return (ENXIO);
|
||||
}
|
||||
@ -1536,43 +1605,31 @@ usb2_ioctl_f(struct file *fp, u_long cmd, void *addr,
|
||||
|
||||
DPRINTFN(2, "fflags=%u, cmd=0x%lx\n", fflags, cmd);
|
||||
|
||||
if (fflags & FREAD) {
|
||||
if (fflags & FWRITE) {
|
||||
/*
|
||||
* Make sure that the IOCTL is not
|
||||
* duplicated:
|
||||
*/
|
||||
is_common = 1;
|
||||
}
|
||||
err_rx = usb2_ioctl_f_sub(loc.rxfifo, cmd, addr, td);
|
||||
if (err_rx == ENOTTY) {
|
||||
err_rx = (loc.rxfifo->methods->f_ioctl) (
|
||||
loc.rxfifo, cmd, addr,
|
||||
is_common ? fflags : (fflags & ~FWRITE), td);
|
||||
}
|
||||
} else {
|
||||
err_rx = 0;
|
||||
}
|
||||
if (fflags & FWRITE) {
|
||||
err_tx = usb2_ioctl_f_sub(loc.txfifo, cmd, addr, td);
|
||||
if (err_tx == ENOTTY) {
|
||||
if (is_common)
|
||||
err_tx = 0; /* already handled this IOCTL */
|
||||
else
|
||||
err_tx = (loc.txfifo->methods->f_ioctl) (
|
||||
loc.txfifo, cmd, addr, fflags & ~FREAD, td);
|
||||
}
|
||||
} else {
|
||||
err_tx = 0;
|
||||
}
|
||||
f = NULL; /* set default value */
|
||||
err = ENOIOCTL; /* set default value */
|
||||
|
||||
if (err_rx) {
|
||||
err = err_rx;
|
||||
} else if (err_tx) {
|
||||
err = err_tx;
|
||||
} else {
|
||||
err = 0; /* no error */
|
||||
if (fflags & FWRITE) {
|
||||
f = loc.txfifo;
|
||||
err = usb2_ioctl_f_sub(f, cmd, addr, td);
|
||||
}
|
||||
if (fflags & FREAD) {
|
||||
f = loc.rxfifo;
|
||||
err = usb2_ioctl_f_sub(f, cmd, addr, td);
|
||||
}
|
||||
if (err == ENOIOCTL) {
|
||||
err = (f->methods->f_ioctl) (f, cmd, addr, fflags, td);
|
||||
if (err == ENOIOCTL) {
|
||||
if (usb2_uref_location(&loc)) {
|
||||
err = ENXIO;
|
||||
goto done;
|
||||
}
|
||||
err = (f->methods->f_ioctl_post) (f, cmd, addr, fflags, td);
|
||||
}
|
||||
}
|
||||
if (err == ENOIOCTL) {
|
||||
err = ENOTTY;
|
||||
}
|
||||
done:
|
||||
usb2_unref_device(&loc);
|
||||
return (err);
|
||||
}
|
||||
@ -1594,7 +1651,6 @@ usb2_poll_f(struct file *fp, int events,
|
||||
struct usb2_mbuf *m;
|
||||
int fflags;
|
||||
int revents;
|
||||
uint8_t usbfs_active = 0;
|
||||
|
||||
revents = usb2_ref_device(fp, &loc, 1 /* no uref */ );;
|
||||
if (revents) {
|
||||
@ -1602,20 +1658,6 @@ usb2_poll_f(struct file *fp, int events,
|
||||
}
|
||||
fflags = fp->f_flag;
|
||||
|
||||
/* figure out if the USB File System is active */
|
||||
|
||||
if (fflags & FWRITE) {
|
||||
f = loc.txfifo;
|
||||
if (f->fs_ep_max != 0) {
|
||||
usbfs_active = 1;
|
||||
}
|
||||
}
|
||||
if (fflags & FREAD) {
|
||||
f = loc.rxfifo;
|
||||
if (f->fs_ep_max != 0) {
|
||||
usbfs_active = 1;
|
||||
}
|
||||
}
|
||||
/* Figure out who needs service */
|
||||
|
||||
if ((events & (POLLOUT | POLLWRNORM)) &&
|
||||
@ -1625,7 +1667,7 @@ usb2_poll_f(struct file *fp, int events,
|
||||
|
||||
mtx_lock(f->priv_mtx);
|
||||
|
||||
if (!usbfs_active) {
|
||||
if (!loc.is_usbfs) {
|
||||
if (f->flag_iserror) {
|
||||
/* we got an error */
|
||||
m = (void *)1;
|
||||
@ -1664,7 +1706,7 @@ usb2_poll_f(struct file *fp, int events,
|
||||
|
||||
mtx_lock(f->priv_mtx);
|
||||
|
||||
if (!usbfs_active) {
|
||||
if (!loc.is_usbfs) {
|
||||
if (f->flag_iserror) {
|
||||
/* we have and error */
|
||||
m = (void *)1;
|
||||
@ -1693,8 +1735,10 @@ usb2_poll_f(struct file *fp, int events,
|
||||
f->flag_isselect = 1;
|
||||
selrecord(td, &f->selinfo);
|
||||
|
||||
/* start reading data */
|
||||
(f->methods->f_start_read) (f);
|
||||
if (!loc.is_usbfs) {
|
||||
/* start reading data */
|
||||
(f->methods->f_start_read) (f);
|
||||
}
|
||||
}
|
||||
|
||||
mtx_unlock(f->priv_mtx);
|
||||
@ -1739,22 +1783,23 @@ usb2_read_f(struct file *fp, struct uio *uio, struct ucred *cred,
|
||||
|
||||
mtx_lock(f->priv_mtx);
|
||||
|
||||
/* check for permanent read error */
|
||||
if (f->flag_iserror) {
|
||||
err = EIO;
|
||||
goto done;
|
||||
}
|
||||
/* check if USB-FS interface is active */
|
||||
if (loc.is_usbfs) {
|
||||
/*
|
||||
* The queue is used for events that should be
|
||||
* retrieved using the "USB_FS_COMPLETE" ioctl.
|
||||
*/
|
||||
err = EINVAL;
|
||||
goto done;
|
||||
}
|
||||
while (uio->uio_resid > 0) {
|
||||
|
||||
if (f->fs_ep_max == 0) {
|
||||
USB_IF_DEQUEUE(&f->used_q, m);
|
||||
} else {
|
||||
/*
|
||||
* The queue is used for events that should be
|
||||
* retrieved using the "USB_FS_COMPLETE"
|
||||
* ioctl.
|
||||
*/
|
||||
m = NULL;
|
||||
}
|
||||
USB_IF_DEQUEUE(&f->used_q, m);
|
||||
|
||||
if (m == NULL) {
|
||||
|
||||
@ -1777,9 +1822,16 @@ usb2_read_f(struct file *fp, struct uio *uio, struct ucred *cred,
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
} else {
|
||||
tr_data = 1;
|
||||
}
|
||||
if (f->methods->f_filter_read) {
|
||||
/*
|
||||
* Sometimes it is convenient to process data at the
|
||||
* expense of a userland process instead of a kernel
|
||||
* process.
|
||||
*/
|
||||
(f->methods->f_filter_read) (f, m);
|
||||
}
|
||||
tr_data = 1;
|
||||
|
||||
io_len = MIN(m->cur_data_len, uio->uio_resid);
|
||||
|
||||
@ -1876,26 +1928,27 @@ usb2_write_f(struct file *fp, struct uio *uio, struct ucred *cred,
|
||||
|
||||
mtx_lock(f->priv_mtx);
|
||||
|
||||
/* check for permanent write error */
|
||||
if (f->flag_iserror) {
|
||||
err = EIO;
|
||||
goto done;
|
||||
}
|
||||
if ((f->queue_data == NULL) && (f->fs_ep_max == 0)) {
|
||||
/* check if USB-FS interface is active */
|
||||
if (loc.is_usbfs) {
|
||||
/*
|
||||
* The queue is used for events that should be
|
||||
* retrieved using the "USB_FS_COMPLETE" ioctl.
|
||||
*/
|
||||
err = EINVAL;
|
||||
goto done;
|
||||
}
|
||||
if (f->queue_data == NULL) {
|
||||
/* start write transfer, if not already started */
|
||||
(f->methods->f_start_write) (f);
|
||||
}
|
||||
/* we allow writing zero length data */
|
||||
do {
|
||||
if (f->fs_ep_max == 0) {
|
||||
USB_IF_DEQUEUE(&f->free_q, m);
|
||||
} else {
|
||||
/*
|
||||
* The queue is used for events that should be
|
||||
* retrieved using the "USB_FS_COMPLETE"
|
||||
* ioctl.
|
||||
*/
|
||||
m = NULL;
|
||||
}
|
||||
USB_IF_DEQUEUE(&f->free_q, m);
|
||||
|
||||
if (m == NULL) {
|
||||
|
||||
@ -1914,9 +1967,8 @@ usb2_write_f(struct file *fp, struct uio *uio, struct ucred *cred,
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
} else {
|
||||
tr_data = 1;
|
||||
}
|
||||
tr_data = 1;
|
||||
|
||||
USB_MBUF_RESET(m);
|
||||
|
||||
@ -1933,10 +1985,19 @@ usb2_write_f(struct file *fp, struct uio *uio, struct ucred *cred,
|
||||
if (err) {
|
||||
USB_IF_ENQUEUE(&f->free_q, m);
|
||||
break;
|
||||
} else {
|
||||
USB_IF_ENQUEUE(&f->used_q, m);
|
||||
(f->methods->f_start_write) (f);
|
||||
}
|
||||
if (f->methods->f_filter_write) {
|
||||
/*
|
||||
* Sometimes it is convenient to process data at the
|
||||
* expense of a userland process instead of a kernel
|
||||
* process.
|
||||
*/
|
||||
(f->methods->f_filter_write) (f, m);
|
||||
}
|
||||
USB_IF_ENQUEUE(&f->used_q, m);
|
||||
|
||||
(f->methods->f_start_write) (f);
|
||||
|
||||
} while (uio->uio_resid > 0);
|
||||
done:
|
||||
mtx_unlock(f->priv_mtx);
|
||||
@ -2066,7 +2127,7 @@ static int
|
||||
usb2_fifo_dummy_ioctl(struct usb2_fifo *fifo, u_long cmd, void *addr,
|
||||
int fflags, struct thread *td)
|
||||
{
|
||||
return (ENOTTY);
|
||||
return (ENOIOCTL);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -2090,6 +2151,9 @@ usb2_fifo_check_methods(struct usb2_fifo_methods *pm)
|
||||
if (pm->f_ioctl == NULL)
|
||||
pm->f_ioctl = &usb2_fifo_dummy_ioctl;
|
||||
|
||||
if (pm->f_ioctl_post == NULL)
|
||||
pm->f_ioctl_post = &usb2_fifo_dummy_ioctl;
|
||||
|
||||
if (pm->f_start_read == NULL)
|
||||
pm->f_start_read = &usb2_fifo_dummy_cmd;
|
||||
|
||||
@ -2173,7 +2237,6 @@ usb2_fifo_attach(struct usb2_device *udev, void *priv_sc,
|
||||
f_tx->methods = pm;
|
||||
f_tx->iface_index = iface_index;
|
||||
f_tx->udev = udev;
|
||||
f_tx->flag_no_uref = 1;
|
||||
|
||||
f_rx->fifo_index = n + USB_FIFO_RX;
|
||||
f_rx->dev_ep_index = (n / 2) + (USB_EP_MAX / 2);
|
||||
@ -2182,7 +2245,6 @@ usb2_fifo_attach(struct usb2_device *udev, void *priv_sc,
|
||||
f_rx->methods = pm;
|
||||
f_rx->iface_index = iface_index;
|
||||
f_rx->udev = udev;
|
||||
f_rx->flag_no_uref = 1;
|
||||
|
||||
f_sc->fp[USB_FIFO_TX] = f_tx;
|
||||
f_sc->fp[USB_FIFO_RX] = f_rx;
|
||||
@ -2561,32 +2623,17 @@ usb2_fifo_get_data_buffer(struct usb2_fifo *f, void **pptr, uint32_t *plen)
|
||||
{
|
||||
struct usb2_mbuf *m;
|
||||
|
||||
USB_IF_DEQUEUE(&f->used_q, m);
|
||||
USB_IF_POLL(&f->used_q, m);
|
||||
|
||||
if (m) {
|
||||
*plen = m->cur_data_len;
|
||||
*pptr = m->cur_data_ptr;
|
||||
|
||||
USB_IF_PREPEND(&f->used_q, m);
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
usb2_fifo_get_data_next(struct usb2_fifo *f)
|
||||
{
|
||||
struct usb2_mbuf *m;
|
||||
|
||||
USB_IF_DEQUEUE(&f->used_q, m);
|
||||
|
||||
if (m) {
|
||||
USB_IF_ENQUEUE(&f->free_q, m);
|
||||
usb2_fifo_wakeup(f);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
usb2_fifo_get_data_error(struct usb2_fifo *f)
|
||||
{
|
||||
|
@ -39,11 +39,13 @@
|
||||
#define USB_FIFO_RX 1
|
||||
|
||||
struct usb2_fifo;
|
||||
struct usb2_mbuf;
|
||||
|
||||
typedef int (usb2_fifo_open_t)(struct usb2_fifo *fifo, int fflags, struct thread *td);
|
||||
typedef void (usb2_fifo_close_t)(struct usb2_fifo *fifo, int fflags, struct thread *td);
|
||||
typedef int (usb2_fifo_ioctl_t)(struct usb2_fifo *fifo, u_long cmd, void *addr, int fflags, struct thread *td);
|
||||
typedef void (usb2_fifo_cmd_t)(struct usb2_fifo *fifo);
|
||||
typedef void (usb2_fifo_filter_t)(struct usb2_fifo *fifo, struct usb2_mbuf *m);
|
||||
|
||||
struct usb2_symlink {
|
||||
TAILQ_ENTRY(usb2_symlink) sym_entry;
|
||||
@ -57,17 +59,24 @@ struct usb2_symlink {
|
||||
|
||||
/*
|
||||
* Locking note for the following functions. All the
|
||||
* "usb2_fifo_cmd_t" functions are called locked. The others are
|
||||
* called unlocked.
|
||||
* "usb2_fifo_cmd_t" and "usb2_fifo_filter_t" functions are called
|
||||
* locked. The others are called unlocked.
|
||||
*/
|
||||
struct usb2_fifo_methods {
|
||||
usb2_fifo_open_t *f_open;
|
||||
usb2_fifo_close_t *f_close;
|
||||
usb2_fifo_ioctl_t *f_ioctl;
|
||||
/*
|
||||
* NOTE: The post-ioctl callback is called after the USB reference
|
||||
* gets locked in the IOCTL handler:
|
||||
*/
|
||||
usb2_fifo_ioctl_t *f_ioctl_post;
|
||||
usb2_fifo_cmd_t *f_start_read;
|
||||
usb2_fifo_cmd_t *f_stop_read;
|
||||
usb2_fifo_cmd_t *f_start_write;
|
||||
usb2_fifo_cmd_t *f_stop_write;
|
||||
usb2_fifo_filter_t *f_filter_read;
|
||||
usb2_fifo_filter_t *f_filter_write;
|
||||
const char *basename[4];
|
||||
const char *postfix[4];
|
||||
};
|
||||
@ -98,7 +107,6 @@ struct usb2_fifo {
|
||||
uint32_t bufsize; /* BULK and INTERRUPT buffer size */
|
||||
uint16_t nframes; /* for isochronous mode */
|
||||
uint16_t dev_ep_index; /* our device endpoint index */
|
||||
uint8_t flag_no_uref; /* set if FIFO is not control endpoint */
|
||||
uint8_t flag_sleeping; /* set if FIFO is sleeping */
|
||||
uint8_t flag_iscomplete; /* set if a USB transfer is complete */
|
||||
uint8_t flag_iserror; /* set if FIFO error happened */
|
||||
@ -134,7 +142,6 @@ void usb2_fifo_put_data_error(struct usb2_fifo *fifo);
|
||||
uint8_t usb2_fifo_get_data(struct usb2_fifo *fifo, struct usb2_page_cache *pc, uint32_t offset, uint32_t len, uint32_t *actlen, uint8_t what);
|
||||
uint8_t usb2_fifo_get_data_linear(struct usb2_fifo *fifo, void *ptr, uint32_t len, uint32_t *actlen, uint8_t what);
|
||||
uint8_t usb2_fifo_get_data_buffer(struct usb2_fifo *f, void **pptr, uint32_t *plen);
|
||||
void usb2_fifo_get_data_next(struct usb2_fifo *f);
|
||||
void usb2_fifo_get_data_error(struct usb2_fifo *fifo);
|
||||
uint8_t usb2_fifo_opened(struct usb2_fifo *fifo);
|
||||
void usb2_fifo_free(struct usb2_fifo *f);
|
||||
|
@ -47,6 +47,7 @@
|
||||
#include <dev/usb2/core/usb2_mbuf.h>
|
||||
#include <dev/usb2/core/usb2_dev.h>
|
||||
#include <dev/usb2/core/usb2_msctest.h>
|
||||
#include <dev/usb2/core/usb2_generic.h>
|
||||
|
||||
#include <dev/usb2/quirk/usb2_quirk.h>
|
||||
|
||||
@ -66,7 +67,7 @@ static void usb2_clear_stall_proc(struct usb2_proc_msg *_pm);
|
||||
static void usb2_check_strings(struct usb2_device *udev);
|
||||
static usb2_error_t usb2_fill_iface_data(struct usb2_device *udev, uint8_t iface_index, uint8_t alt_index);
|
||||
static void usb2_notify_addq(const char *type, struct usb2_device *udev);
|
||||
static void usb2_fifo_free_wrap(struct usb2_device *udev, uint8_t iface_index, uint8_t free_all);
|
||||
static void usb2_fifo_free_wrap(struct usb2_device *udev, uint8_t iface_index, uint8_t flag);
|
||||
|
||||
/* static structures */
|
||||
|
||||
@ -672,7 +673,10 @@ usb2_set_alt_interface_index(struct usb2_device *udev,
|
||||
if (udev->flags.usb2_mode == USB_MODE_DEVICE) {
|
||||
usb2_detach_device(udev, iface_index, 1);
|
||||
}
|
||||
/* free all FIFOs for this interface */
|
||||
/*
|
||||
* Free all generic FIFOs for this interface, except control
|
||||
* endpoint FIFOs:
|
||||
*/
|
||||
usb2_fifo_free_wrap(udev, iface_index, 0);
|
||||
|
||||
err = usb2_fill_iface_data(udev, iface_index, alt_index);
|
||||
@ -2077,14 +2081,20 @@ usb2_notify_addq(const char *type, struct usb2_device *udev)
|
||||
/*------------------------------------------------------------------------*
|
||||
* usb2_fifo_free_wrap
|
||||
*
|
||||
* The function will free the FIFOs.
|
||||
* This function will free the FIFOs.
|
||||
*
|
||||
* Flag values, if "iface_index" is equal to "USB_IFACE_INDEX_ANY".
|
||||
* 0: Free all FIFOs except generic control endpoints.
|
||||
* 1: Free all FIFOs.
|
||||
*
|
||||
* Flag values, if "iface_index" is not equal to "USB_IFACE_INDEX_ANY".
|
||||
* Not used.
|
||||
*------------------------------------------------------------------------*/
|
||||
static void
|
||||
usb2_fifo_free_wrap(struct usb2_device *udev,
|
||||
uint8_t iface_index, uint8_t free_all)
|
||||
uint8_t iface_index, uint8_t flag)
|
||||
{
|
||||
struct usb2_fifo *f;
|
||||
struct usb2_pipe *pipe;
|
||||
uint16_t i;
|
||||
|
||||
/*
|
||||
@ -2095,16 +2105,48 @@ usb2_fifo_free_wrap(struct usb2_device *udev,
|
||||
if (f == NULL) {
|
||||
continue;
|
||||
}
|
||||
pipe = f->priv_sc0;
|
||||
if ((pipe == &udev->default_pipe) && (free_all == 0)) {
|
||||
/* don't free UGEN control endpoint yet */
|
||||
/* Check if the interface index matches */
|
||||
if (iface_index == f->iface_index) {
|
||||
if (f->methods != &usb2_ugen_methods) {
|
||||
/*
|
||||
* Don't free any non-generic FIFOs in
|
||||
* this case.
|
||||
*/
|
||||
continue;
|
||||
}
|
||||
if (f->dev_ep_index == 0) {
|
||||
/*
|
||||
* Don't free the generic control endpoint
|
||||
* yet and make sure that any USB-FS
|
||||
* activity is stopped!
|
||||
*/
|
||||
if (ugen_fs_uninit(f)) {
|
||||
/* ignore any failures */
|
||||
DPRINTFN(10, "udev=%p ugen_fs_uninit() "
|
||||
"failed! (ignored)\n", udev);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
} else if (iface_index == USB_IFACE_INDEX_ANY) {
|
||||
if ((f->methods == &usb2_ugen_methods) &&
|
||||
(f->dev_ep_index == 0) && (flag == 0)) {
|
||||
/*
|
||||
* Don't free the generic control endpoint
|
||||
* yet, but make sure that any USB-FS
|
||||
* activity is stopped!
|
||||
*/
|
||||
if (ugen_fs_uninit(f)) {
|
||||
/* ignore any failures */
|
||||
DPRINTFN(10, "udev=%p ugen_fs_uninit() "
|
||||
"failed! (ignored)\n", udev);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
/* Check if the interface index matches */
|
||||
if ((iface_index == f->iface_index) ||
|
||||
(iface_index == USB_IFACE_INDEX_ANY)) {
|
||||
usb2_fifo_free(f);
|
||||
}
|
||||
/* free the FIFO */
|
||||
usb2_fifo_free(f);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -67,6 +67,7 @@ static usb2_callback_t ugen_default_fs_callback;
|
||||
static usb2_fifo_open_t ugen_open;
|
||||
static usb2_fifo_close_t ugen_close;
|
||||
static usb2_fifo_ioctl_t ugen_ioctl;
|
||||
static usb2_fifo_ioctl_t ugen_ioctl_post;
|
||||
static usb2_fifo_cmd_t ugen_start_read;
|
||||
static usb2_fifo_cmd_t ugen_start_write;
|
||||
static usb2_fifo_cmd_t ugen_stop_io;
|
||||
@ -81,8 +82,6 @@ static int ugen_get_sdesc(struct usb2_fifo *f, struct usb2_gen_descriptor *ugd);
|
||||
static int usb2_gen_fill_deviceinfo(struct usb2_fifo *f, struct usb2_device_info *di);
|
||||
static int ugen_re_enumerate(struct usb2_fifo *f);
|
||||
static int ugen_iface_ioctl(struct usb2_fifo *f, u_long cmd, void *addr, int fflags);
|
||||
static int ugen_ctrl_ioctl(struct usb2_fifo *f, u_long cmd, void *addr, int fflags);
|
||||
static int ugen_fs_uninit(struct usb2_fifo *f);
|
||||
static uint8_t ugen_fs_get_complete(struct usb2_fifo *f, uint8_t *pindex);
|
||||
|
||||
|
||||
@ -92,6 +91,7 @@ struct usb2_fifo_methods usb2_ugen_methods = {
|
||||
.f_open = &ugen_open,
|
||||
.f_close = &ugen_close,
|
||||
.f_ioctl = &ugen_ioctl,
|
||||
.f_ioctl_post = &ugen_ioctl_post,
|
||||
.f_start_read = &ugen_start_read,
|
||||
.f_stop_read = &ugen_stop_io,
|
||||
.f_start_write = &ugen_start_write,
|
||||
@ -209,10 +209,6 @@ ugen_open_pipe_write(struct usb2_fifo *f)
|
||||
/* transfers are already opened */
|
||||
return (0);
|
||||
}
|
||||
if (f->fs_xfer) {
|
||||
/* should not happen */
|
||||
return (EINVAL);
|
||||
}
|
||||
bzero(usb2_config, sizeof(usb2_config));
|
||||
|
||||
usb2_config[1].type = UE_CONTROL;
|
||||
@ -281,10 +277,6 @@ ugen_open_pipe_read(struct usb2_fifo *f)
|
||||
/* transfers are already opened */
|
||||
return (0);
|
||||
}
|
||||
if (f->fs_xfer) {
|
||||
/* should not happen */
|
||||
return (EINVAL);
|
||||
}
|
||||
bzero(usb2_config, sizeof(usb2_config));
|
||||
|
||||
usb2_config[1].type = UE_CONTROL;
|
||||
@ -591,10 +583,6 @@ ugen_set_config(struct usb2_fifo *f, uint8_t index)
|
||||
{
|
||||
DPRINTFN(2, "index %u\n", index);
|
||||
|
||||
if (f->flag_no_uref) {
|
||||
/* not the control endpoint - just forget it */
|
||||
return (EINVAL);
|
||||
}
|
||||
if (f->udev->flags.usb2_mode != USB_MODE_HOST) {
|
||||
/* not possible in device side mode */
|
||||
return (ENOTTY);
|
||||
@ -620,10 +608,6 @@ ugen_set_interface(struct usb2_fifo *f,
|
||||
{
|
||||
DPRINTFN(2, "%u, %u\n", iface_index, alt_index);
|
||||
|
||||
if (f->flag_no_uref) {
|
||||
/* not the control endpoint - just forget it */
|
||||
return (EINVAL);
|
||||
}
|
||||
if (f->udev->flags.usb2_mode != USB_MODE_HOST) {
|
||||
/* not possible in device side mode */
|
||||
return (ENOTTY);
|
||||
@ -656,10 +640,6 @@ ugen_get_cdesc(struct usb2_fifo *f, struct usb2_gen_descriptor *ugd)
|
||||
|
||||
DPRINTFN(6, "\n");
|
||||
|
||||
if (f->flag_no_uref) {
|
||||
/* control endpoint only */
|
||||
return (EINVAL);
|
||||
}
|
||||
if (ugd->ugd_data == NULL) {
|
||||
/* userland pointer should not be zero */
|
||||
return (EINVAL);
|
||||
@ -705,10 +685,6 @@ ugen_get_sdesc(struct usb2_fifo *f, struct usb2_gen_descriptor *ugd)
|
||||
uint16_t size = sizeof(f->udev->bus->scratch[0].data);
|
||||
int error;
|
||||
|
||||
if (f->flag_no_uref) {
|
||||
/* control endpoint only */
|
||||
return (EINVAL);
|
||||
}
|
||||
if (usb2_req_get_string_desc(f->udev, &Giant, ptr,
|
||||
size, ugd->ugd_lang_id, ugd->ugd_string_index)) {
|
||||
error = EINVAL;
|
||||
@ -751,10 +727,6 @@ usb2_gen_fill_devicenames(struct usb2_fifo *f, struct usb2_device_names *dn)
|
||||
uint8_t i;
|
||||
uint8_t first = 1;
|
||||
|
||||
if (f->flag_no_uref) {
|
||||
/* control endpoint only */
|
||||
return (EINVAL);
|
||||
}
|
||||
max_len = dn->udn_devnames_len;
|
||||
dst = dn->udn_devnames_ptr;
|
||||
|
||||
@ -813,10 +785,6 @@ usb2_gen_fill_deviceinfo(struct usb2_fifo *f, struct usb2_device_info *di)
|
||||
struct usb2_device *udev;
|
||||
struct usb2_device *hub;
|
||||
|
||||
if (f->flag_no_uref) {
|
||||
/* control endpoint only */
|
||||
return (EINVAL);
|
||||
}
|
||||
udev = f->udev;
|
||||
|
||||
bzero(di, sizeof(di[0]));
|
||||
@ -919,10 +887,6 @@ ugen_do_request(struct usb2_fifo *f, struct usb2_ctl_request *ur)
|
||||
uint16_t len;
|
||||
uint16_t actlen;
|
||||
|
||||
if (f->flag_no_uref) {
|
||||
/* control endpoint only */
|
||||
return (EINVAL);
|
||||
}
|
||||
if (ugen_check_request(f->udev, &ur->ucr_request)) {
|
||||
return (EPERM);
|
||||
}
|
||||
@ -958,10 +922,6 @@ ugen_re_enumerate(struct usb2_fifo *f)
|
||||
struct usb2_device *udev = f->udev;
|
||||
int error;
|
||||
|
||||
if (f->flag_no_uref) {
|
||||
/* control endpoint only */
|
||||
return (EINVAL);
|
||||
}
|
||||
/*
|
||||
* This request can be useful for testing USB drivers:
|
||||
*/
|
||||
@ -969,6 +929,12 @@ ugen_re_enumerate(struct usb2_fifo *f)
|
||||
if (error) {
|
||||
return (error);
|
||||
}
|
||||
/* get the device unconfigured */
|
||||
error = ugen_set_config(f, USB_UNCONFIG_INDEX);
|
||||
if (error) {
|
||||
return (error);
|
||||
}
|
||||
/* do a bus-reset */
|
||||
mtx_lock(f->priv_mtx);
|
||||
error = usb2_req_re_enumerate(udev, f->priv_mtx);
|
||||
mtx_unlock(f->priv_mtx);
|
||||
@ -976,10 +942,15 @@ ugen_re_enumerate(struct usb2_fifo *f)
|
||||
if (error) {
|
||||
return (ENXIO);
|
||||
}
|
||||
/* restore configuration to index 0 */
|
||||
error = ugen_set_config(f, 0);
|
||||
if (error) {
|
||||
return (error);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
int
|
||||
ugen_fs_uninit(struct usb2_fifo *f)
|
||||
{
|
||||
if (f->fs_xfer == NULL) {
|
||||
@ -991,7 +962,6 @@ ugen_fs_uninit(struct usb2_fifo *f)
|
||||
f->fs_ep_max = 0;
|
||||
f->fs_ep_ptr = NULL;
|
||||
f->flag_iscomplete = 0;
|
||||
f->flag_no_uref = 0; /* restore operation */
|
||||
usb2_fifo_free_buffer(f);
|
||||
return (0);
|
||||
}
|
||||
@ -1393,7 +1363,8 @@ ugen_fifo_in_use(struct usb2_fifo *f, int fflags)
|
||||
}
|
||||
|
||||
static int
|
||||
ugen_fs_ioctl(struct usb2_fifo *f, u_long cmd, void *addr, int fflags)
|
||||
ugen_ioctl(struct usb2_fifo *f, u_long cmd, void *addr, int fflags,
|
||||
struct thread *td)
|
||||
{
|
||||
struct usb2_config usb2_config[1];
|
||||
struct usb2_device_request req;
|
||||
@ -1401,8 +1372,6 @@ ugen_fs_ioctl(struct usb2_fifo *f, u_long cmd, void *addr, int fflags)
|
||||
struct usb2_fs_complete *pcomp;
|
||||
struct usb2_fs_start *pstart;
|
||||
struct usb2_fs_stop *pstop;
|
||||
struct usb2_fs_init *pinit;
|
||||
struct usb2_fs_uninit *puninit;
|
||||
struct usb2_fs_open *popen;
|
||||
struct usb2_fs_close *pclose;
|
||||
struct usb2_fs_clear_stall_sync *pstall;
|
||||
@ -1417,6 +1386,8 @@ ugen_fs_ioctl(struct usb2_fifo *f, u_long cmd, void *addr, int fflags)
|
||||
|
||||
u.addr = addr;
|
||||
|
||||
DPRINTFN(6, "cmd=0x%08lx\n", cmd);
|
||||
|
||||
switch (cmd) {
|
||||
case USB_FS_COMPLETE:
|
||||
mtx_lock(f->priv_mtx);
|
||||
@ -1451,59 +1422,6 @@ ugen_fs_ioctl(struct usb2_fifo *f, u_long cmd, void *addr, int fflags)
|
||||
mtx_unlock(f->priv_mtx);
|
||||
break;
|
||||
|
||||
case USB_FS_INIT:
|
||||
/* verify input parameters */
|
||||
if (u.pinit->pEndpoints == NULL) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
if (u.pinit->ep_index_max > 127) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
if (u.pinit->ep_index_max == 0) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
if (f->fs_xfer != NULL) {
|
||||
error = EBUSY;
|
||||
break;
|
||||
}
|
||||
if (f->flag_no_uref) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
if (f->dev_ep_index != 0) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
if (ugen_fifo_in_use(f, fflags)) {
|
||||
error = EBUSY;
|
||||
break;
|
||||
}
|
||||
error = usb2_fifo_alloc_buffer(f, 1, u.pinit->ep_index_max);
|
||||
if (error) {
|
||||
break;
|
||||
}
|
||||
f->fs_xfer = malloc(sizeof(f->fs_xfer[0]) *
|
||||
u.pinit->ep_index_max, M_USB, M_WAITOK | M_ZERO);
|
||||
if (f->fs_xfer == NULL) {
|
||||
usb2_fifo_free_buffer(f);
|
||||
error = ENOMEM;
|
||||
break;
|
||||
}
|
||||
f->fs_ep_max = u.pinit->ep_index_max;
|
||||
f->fs_ep_ptr = u.pinit->pEndpoints;
|
||||
break;
|
||||
|
||||
case USB_FS_UNINIT:
|
||||
if (u.puninit->dummy != 0) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
error = ugen_fs_uninit(f);
|
||||
break;
|
||||
|
||||
case USB_FS_OPEN:
|
||||
if (u.popen->ep_index >= f->fs_ep_max) {
|
||||
error = EINVAL;
|
||||
@ -1591,11 +1509,6 @@ ugen_fs_ioctl(struct usb2_fifo *f, u_long cmd, void *addr, int fflags)
|
||||
f->fs_xfer[u.popen->ep_index]->max_data_length;
|
||||
f->fs_xfer[u.popen->ep_index]->priv_fifo =
|
||||
((uint8_t *)0) + u.popen->ep_index;
|
||||
/*
|
||||
* Increase performance by dropping locks we
|
||||
* don't need:
|
||||
*/
|
||||
f->flag_no_uref = 1;
|
||||
} else {
|
||||
error = ENOMEM;
|
||||
}
|
||||
@ -1652,9 +1565,12 @@ ugen_fs_ioctl(struct usb2_fifo *f, u_long cmd, void *addr, int fflags)
|
||||
break;
|
||||
|
||||
default:
|
||||
error = ENOTTY;
|
||||
error = ENOIOCTL;
|
||||
break;
|
||||
}
|
||||
|
||||
DPRINTFN(6, "error=%d\n", error);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -2007,14 +1923,15 @@ ugen_iface_ioctl(struct usb2_fifo *f, u_long cmd, void *addr, int fflags)
|
||||
break;
|
||||
|
||||
default:
|
||||
error = ENOTTY;
|
||||
error = ENOIOCTL;
|
||||
break;
|
||||
}
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
ugen_ctrl_ioctl(struct usb2_fifo *f, u_long cmd, void *addr, int fflags)
|
||||
ugen_ioctl_post(struct usb2_fifo *f, u_long cmd, void *addr, int fflags,
|
||||
struct thread *td)
|
||||
{
|
||||
union {
|
||||
struct usb2_interface_descriptor *idesc;
|
||||
@ -2022,6 +1939,8 @@ ugen_ctrl_ioctl(struct usb2_fifo *f, u_long cmd, void *addr, int fflags)
|
||||
struct usb2_device_descriptor *ddesc;
|
||||
struct usb2_config_descriptor *cdesc;
|
||||
struct usb2_device_stats *stat;
|
||||
struct usb2_fs_init *pinit;
|
||||
struct usb2_fs_uninit *puninit;
|
||||
uint32_t *ptime;
|
||||
void *addr;
|
||||
int *pint;
|
||||
@ -2034,6 +1953,8 @@ ugen_ctrl_ioctl(struct usb2_fifo *f, u_long cmd, void *addr, int fflags)
|
||||
|
||||
u.addr = addr;
|
||||
|
||||
DPRINTFN(6, "cmd=0x%08lx\n", cmd);
|
||||
|
||||
switch (cmd) {
|
||||
case USB_DISCOVER:
|
||||
usb2_needs_explore_all();
|
||||
@ -2178,29 +2099,60 @@ ugen_ctrl_ioctl(struct usb2_fifo *f, u_long cmd, void *addr, int fflags)
|
||||
*u.pint, 0, UHF_PORT_ENABLE);
|
||||
break;
|
||||
|
||||
default:
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
ugen_ioctl(struct usb2_fifo *f, u_long cmd, void *addr, int fflags,
|
||||
struct thread *td)
|
||||
{
|
||||
int error;
|
||||
|
||||
DPRINTFN(6, "cmd=%08lx\n", cmd);
|
||||
error = ugen_fs_ioctl(f, cmd, addr, fflags);
|
||||
if (error == ENOTTY) {
|
||||
if (f->flag_no_uref) {
|
||||
mtx_lock(f->priv_mtx);
|
||||
error = ugen_iface_ioctl(f, cmd, addr, fflags);
|
||||
mtx_unlock(f->priv_mtx);
|
||||
} else {
|
||||
error = ugen_ctrl_ioctl(f, cmd, addr, fflags);
|
||||
case USB_FS_INIT:
|
||||
/* verify input parameters */
|
||||
if (u.pinit->pEndpoints == NULL) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
if (u.pinit->ep_index_max > 127) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
if (u.pinit->ep_index_max == 0) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
if (f->fs_xfer != NULL) {
|
||||
error = EBUSY;
|
||||
break;
|
||||
}
|
||||
if (f->dev_ep_index != 0) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
if (ugen_fifo_in_use(f, fflags)) {
|
||||
error = EBUSY;
|
||||
break;
|
||||
}
|
||||
error = usb2_fifo_alloc_buffer(f, 1, u.pinit->ep_index_max);
|
||||
if (error) {
|
||||
break;
|
||||
}
|
||||
f->fs_xfer = malloc(sizeof(f->fs_xfer[0]) *
|
||||
u.pinit->ep_index_max, M_USB, M_WAITOK | M_ZERO);
|
||||
if (f->fs_xfer == NULL) {
|
||||
usb2_fifo_free_buffer(f);
|
||||
error = ENOMEM;
|
||||
break;
|
||||
}
|
||||
f->fs_ep_max = u.pinit->ep_index_max;
|
||||
f->fs_ep_ptr = u.pinit->pEndpoints;
|
||||
break;
|
||||
|
||||
case USB_FS_UNINIT:
|
||||
if (u.puninit->dummy != 0) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
error = ugen_fs_uninit(f);
|
||||
break;
|
||||
|
||||
default:
|
||||
mtx_lock(f->priv_mtx);
|
||||
error = ugen_iface_ioctl(f, cmd, addr, fflags);
|
||||
mtx_unlock(f->priv_mtx);
|
||||
break;
|
||||
}
|
||||
DPRINTFN(6, "error=%d\n", error);
|
||||
return (error);
|
||||
|
@ -29,5 +29,6 @@
|
||||
|
||||
extern struct usb2_fifo_methods usb2_ugen_methods;
|
||||
int ugen_do_request(struct usb2_fifo *f, struct usb2_ctl_request *ur);
|
||||
int ugen_fs_uninit(struct usb2_fifo *f);
|
||||
|
||||
#endif /* _USB2_GENERIC_H_ */
|
||||
|
@ -72,6 +72,7 @@ struct uhub_softc {
|
||||
struct usb2_device *sc_udev; /* USB device */
|
||||
struct usb2_xfer *sc_xfer[2]; /* interrupt xfer */
|
||||
uint8_t sc_flags;
|
||||
#define UHUB_FLAG_DID_EXPLORE 0x01
|
||||
#define UHUB_FLAG_INTR_STALL 0x02
|
||||
char sc_name[32];
|
||||
};
|
||||
@ -511,6 +512,14 @@ uhub_explore(struct usb2_device *udev)
|
||||
/* most likely the HUB is gone */
|
||||
break;
|
||||
}
|
||||
if (!(sc->sc_flags & UHUB_FLAG_DID_EXPLORE)) {
|
||||
/*
|
||||
* Fake a connect status change so that the
|
||||
* status gets checked initially!
|
||||
*/
|
||||
sc->sc_st.port_change |=
|
||||
UPS_C_CONNECT_STATUS;
|
||||
}
|
||||
if (sc->sc_st.port_change & UPS_C_PORT_ENABLED) {
|
||||
err = usb2_req_clear_port_feature(
|
||||
udev, &Giant, portno, UHF_C_PORT_ENABLE);
|
||||
@ -533,7 +542,8 @@ uhub_explore(struct usb2_device *udev)
|
||||
DPRINTFN(0, "port error, giving up "
|
||||
"port %d\n", portno);
|
||||
} else {
|
||||
sc->sc_st.port_change |= UPS_C_CONNECT_STATUS;
|
||||
sc->sc_st.port_change |=
|
||||
UPS_C_CONNECT_STATUS;
|
||||
up->restartcnt++;
|
||||
}
|
||||
}
|
||||
@ -560,6 +570,11 @@ uhub_explore(struct usb2_device *udev)
|
||||
/* explore succeeded - reset restart counter */
|
||||
up->restartcnt = 0;
|
||||
}
|
||||
|
||||
/* initial status checked */
|
||||
sc->sc_flags |= UHUB_FLAG_DID_EXPLORE;
|
||||
|
||||
/* return success */
|
||||
return (USB_ERR_NORMAL_COMPLETION);
|
||||
}
|
||||
|
||||
|
@ -686,24 +686,26 @@ usb2_req_get_string_any(struct usb2_device *udev, struct mtx *mtx, char *buf,
|
||||
/* should not happen */
|
||||
return (USB_ERR_NORMAL_COMPLETION);
|
||||
}
|
||||
buf[0] = 0;
|
||||
|
||||
if (string_index == 0) {
|
||||
/* this is the language table */
|
||||
buf[0] = 0;
|
||||
return (USB_ERR_INVAL);
|
||||
}
|
||||
if (udev->flags.no_strings) {
|
||||
buf[0] = 0;
|
||||
return (USB_ERR_STALLED);
|
||||
}
|
||||
err = usb2_req_get_string_desc
|
||||
(udev, mtx, buf, len, udev->langid, string_index);
|
||||
if (err) {
|
||||
buf[0] = 0;
|
||||
return (err);
|
||||
}
|
||||
temp = (uint8_t *)buf;
|
||||
|
||||
if (temp[0] < 2) {
|
||||
/* string length is too short */
|
||||
buf[0] = 0;
|
||||
return (USB_ERR_INVAL);
|
||||
}
|
||||
/* reserve one byte for terminating zero */
|
||||
@ -735,7 +737,8 @@ usb2_req_get_string_any(struct usb2_device *udev, struct mtx *mtx, char *buf,
|
||||
*s = c >> 8;
|
||||
swap = 2;
|
||||
} else {
|
||||
*s = '.';
|
||||
/* silently skip bad character */
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -743,11 +746,12 @@ usb2_req_get_string_any(struct usb2_device *udev, struct mtx *mtx, char *buf,
|
||||
* signs because they might confuse the dmesg printouts!
|
||||
*/
|
||||
if ((*s == '<') || (*s == '>') || (!isprint(*s))) {
|
||||
*s = '.';
|
||||
/* silently skip bad character */
|
||||
continue;
|
||||
}
|
||||
s++;
|
||||
}
|
||||
*s = 0;
|
||||
*s = 0; /* zero terminate resulting string */
|
||||
return (USB_ERR_NORMAL_COMPLETION);
|
||||
}
|
||||
|
||||
@ -1310,6 +1314,10 @@ usb2_req_get_config(struct usb2_device *udev, struct mtx *mtx, uint8_t *pconf)
|
||||
/*------------------------------------------------------------------------*
|
||||
* usb2_req_re_enumerate
|
||||
*
|
||||
* NOTE: After this function returns the hardware is in the
|
||||
* unconfigured state! The application is responsible for setting a
|
||||
* new configuration.
|
||||
*
|
||||
* Returns:
|
||||
* 0: Success
|
||||
* Else: Failure
|
||||
@ -1365,12 +1373,5 @@ usb2_req_re_enumerate(struct usb2_device *udev, struct mtx *mtx)
|
||||
done:
|
||||
/* restore address */
|
||||
udev->address = old_addr;
|
||||
|
||||
if (err == 0) {
|
||||
/* restore configuration */
|
||||
err = usb2_req_set_config(udev, mtx, udev->curr_config_no);
|
||||
/* wait a little bit, just in case */
|
||||
usb2_pause_mtx(mtx, 10);
|
||||
}
|
||||
return (err);
|
||||
}
|
||||
|
@ -89,7 +89,7 @@ device_set_usb2_desc(device_t dev)
|
||||
}
|
||||
uaa = device_get_ivars(dev);
|
||||
if (uaa == NULL) {
|
||||
/* can happend if called at the wrong time */
|
||||
/* can happen if called at the wrong time */
|
||||
return;
|
||||
}
|
||||
udev = uaa->device;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -67,7 +67,7 @@ __FBSDID("$FreeBSD$");
|
||||
static int uscanner_debug = 0;
|
||||
|
||||
SYSCTL_NODE(_hw_usb2, OID_AUTO, uscanner, CTLFLAG_RW, 0, "USB uscanner");
|
||||
SYSCTL_INT(_hw_usb2_uscanner, OID_AUTO, uscanner, CTLFLAG_RW, &uscanner_debug,
|
||||
SYSCTL_INT(_hw_usb2_uscanner, OID_AUTO, debug, CTLFLAG_RW, &uscanner_debug,
|
||||
0, "uscanner debug level");
|
||||
#endif
|
||||
|
||||
|
@ -6,8 +6,8 @@
|
||||
S=${.CURDIR}/../../..
|
||||
|
||||
all:
|
||||
awk -f $S/tools/usbdevs2h.awk $S/dev/usb2/core/usbdevs -d ; mv usbdevs_data.h usb2_devtable.h
|
||||
awk -f $S/tools/usbdevs2h.awk $S/dev/usb2/core/usbdevs -h ; mv usbdevs.h usb2_devid.h
|
||||
awk -f $S/tools/usbdevs2h.awk $S/dev/usb/usbdevs -d ; mv usbdevs_data.h usb2_devtable.h
|
||||
awk -f $S/tools/usbdevs2h.awk $S/dev/usb/usbdevs -h ; mv usbdevs.h usb2_devid.h
|
||||
|
||||
clean:
|
||||
rm -f usb2_devtable.h usb2_devid.h
|
||||
|
@ -1,41 +0,0 @@
|
||||
/*-
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (C) 2000 Cesar Miquel (miquel@df.uba.ar)
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted under any licence of your choise which
|
||||
meets the open source licence definiton
|
||||
http://www.opensource.org/opd.html such as the GNU licence or the
|
||||
BSD licence.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License or the BSD license for more details.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Modified for FreeBSD by Iwasa Kazmi <kzmi@ca2.so-net.ne.jp>
|
||||
|
||||
---------------------------------------------------------------------- */
|
||||
|
||||
/* $FreeBSD$ */
|
||||
|
||||
#include <sys/ioccom.h>
|
||||
|
||||
struct RioCommand {
|
||||
uint16_t length;
|
||||
int request;
|
||||
int requesttype;
|
||||
int value;
|
||||
int index;
|
||||
void *buffer;
|
||||
int timeout;
|
||||
};
|
||||
|
||||
#define RIO_SEND_COMMAND _IOWR('U', 200, struct RioCommand)
|
||||
#define RIO_RECV_COMMAND _IOWR('U', 201, struct RioCommand)
|
||||
|
||||
#define RIO_DIR_OUT 0x0
|
||||
#define RIO_DIR_IN 0x1
|
@ -1,10 +1,10 @@
|
||||
/* $FreeBSD$ */
|
||||
/* ??? */
|
||||
|
||||
/*
|
||||
* THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT.
|
||||
*
|
||||
* generated from:
|
||||
* FreeBSD: src/sys/dev/usb/usbdevs,v 1.372 2008/09/19 09:04:06 kevlo Exp
|
||||
* FreeBSD: src/sys/dev/usb/usbdevs,v 1.381 2008/11/02 03:00:36 imp Exp
|
||||
*/
|
||||
/* $NetBSD: usbdevs,v 1.392 2004/12/29 08:38:44 imp Exp $ */
|
||||
|
||||
@ -951,6 +951,7 @@
|
||||
#define USB_PRODUCT_BELKIN_F5D7050 0x7050 /* F5D7050 Wireless Adapter */
|
||||
#define USB_PRODUCT_BELKIN_F5D7051 0x7051 /* F5D7051 54g USB Network Adapter */
|
||||
#define USB_PRODUCT_BELKIN_F5D7050A 0x705a /* F5D7050A Wireless Adapter */
|
||||
/* Also sold as 'Ativa 802.11g wireless card' */
|
||||
#define USB_PRODUCT_BELKIN_F5D7050_V4000 0x705c /* F5D7050 v4000 Wireless Adapter */
|
||||
#define USB_PRODUCT_BELKIN_F5D9050V3 0x905b /* F5D9050 ver 3 Wireless Adapter */
|
||||
#define USB_PRODUCT_BELKIN2_F5U002 0x0002 /* F5U002 Parallel printer */
|
||||
@ -1431,6 +1432,7 @@
|
||||
#define USB_PRODUCT_HP_640C 0x2004 /* DeskJet 640c */
|
||||
#define USB_PRODUCT_HP_4670V 0x3005 /* ScanJet 4670v */
|
||||
#define USB_PRODUCT_HP_P1100 0x3102 /* Photosmart P1100 */
|
||||
#define USB_PRODUCT_HP_OJ4215 0x3d11 /* OfficeJet 4215 */
|
||||
#define USB_PRODUCT_HP_HN210E 0x811c /* Ethernet HN210E */
|
||||
#define USB_PRODUCT_HP2_C500 0x6002 /* PhotoSmart C500 */
|
||||
|
||||
@ -1441,7 +1443,7 @@
|
||||
|
||||
/* HUAWEI products */
|
||||
#define USB_PRODUCT_HUAWEI_MOBILE 0x1001 /* Huawei Mobile */
|
||||
#define USB_PRODUCT_HUAWEI_E270 0x1003 /* Huawei HSPA modem */
|
||||
#define USB_PRODUCT_HUAWEI_E220 0x1003 /* Huawei HSDPA modem */
|
||||
|
||||
/* HUAWEI 3com products */
|
||||
#define USB_PRODUCT_HUAWEI3COM_WUB320G 0x0009 /* Aolynk WUB320g */
|
||||
@ -1846,7 +1848,7 @@
|
||||
#define USB_PRODUCT_NOVATEL_ES620 0x2100 /* ES620 CDMA */
|
||||
#define USB_PRODUCT_NOVATEL_U720 0x2110 /* Merlin U720 */
|
||||
#define USB_PRODUCT_NOVATEL_U727 0x4100 /* Merlin U727 CDMA */
|
||||
#define USB_PRODUCT_NOVATEL_U950D 0x4400 /* Novatel MC950D HSUPA */
|
||||
#define USB_PRODUCT_NOVATEL_MC950D 0x4400 /* Novatel MC950D HSUPA */
|
||||
#define USB_PRODUCT_NOVATEL_ZEROCD 0x5010 /* Novatel ZeroCD */
|
||||
#define USB_PRODUCT_NOVATEL2_FLEXPACKGPS 0x0100 /* NovAtel FlexPack GPS receiver */
|
||||
|
||||
@ -1862,6 +1864,7 @@
|
||||
#define USB_PRODUCT_OMNIVISION_OV511PLUS 0xa511 /* OV511+ Camera */
|
||||
|
||||
/* OnSpec Electronic, Inc. */
|
||||
#define USB_PRODUCT_ONSPEC_SDS_HOTFIND_D 0x0400 /* SDS-infrared.com Hotfind-D Infrared Camera */
|
||||
#define USB_PRODUCT_ONSPEC_MDCFE_B_CF_READER 0xa000 /* MDCFE-B USB CF Reader */
|
||||
#define USB_PRODUCT_ONSPEC_CFMS_RW 0xa001 /* SIIG/Datafab Memory Stick+CF Reader/Writer */
|
||||
#define USB_PRODUCT_ONSPEC_READER 0xa003 /* Datafab-based Reader */
|
||||
@ -1878,6 +1881,7 @@
|
||||
#define USB_PRODUCT_OPTION_GT3GQUAD 0x6300 /* GlobeTrotter 3G QUAD datacard */
|
||||
#define USB_PRODUCT_OPTION_GT3GPLUS 0x6600 /* GlobeTrotter 3G+ datacard */
|
||||
#define USB_PRODUCT_OPTION_GTMAX36 0x6701 /* GlobeTrotter Max 3.6 Modem */
|
||||
#define USB_PRODUCT_OPTION_GTMAXHSUPA 0x7001 /* GlobeTrotter HSUPA */
|
||||
|
||||
/* OQO */
|
||||
#define USB_PRODUCT_OQO_WIFI01 0x0002 /* model 01 WiFi interface */
|
||||
@ -2001,6 +2005,7 @@
|
||||
#define USB_PRODUCT_QUALCOMM2_RWT_FCT 0x3100 /* RWT FCT-CDMA 2000 1xRTT modem */
|
||||
#define USB_PRODUCT_QUALCOMM2_CDMA_MSM 0x3196 /* CDMA Technologies MSM modem */
|
||||
#define USB_PRODUCT_QUALCOMMINC_CDMA_MSM 0x0001 /* CDMA Technologies MSM modem */
|
||||
#define USB_PRODUCT_QUALCOMMINC_ZTE_STOR 0x2000 /* USB ZTE Storage */
|
||||
|
||||
/* Qtronix products */
|
||||
#define USB_PRODUCT_QTRONIX_980N 0x2011 /* Scorpion-980N keyboard */
|
||||
@ -2237,6 +2242,7 @@
|
||||
#define USB_PRODUCT_SONY_CLIE_NX60 0x00da /* Sony Clie nx60 */
|
||||
#define USB_PRODUCT_SONY_CLIE_TH55 0x0144 /* Sony Clie th55 */
|
||||
#define USB_PRODUCT_SONY_CLIE_TJ37 0x0169 /* Sony Clie tj37 */
|
||||
#define USB_PRODUCT_SONY_RF_RECEIVER 0x01db /* Sony RF mouse/kbd Receiver VGP-WRC1 */
|
||||
|
||||
/* Sony Ericsson products */
|
||||
#define USB_PRODUCT_SONYERICSSON_DCU10 0x0528 /* USB Cable */
|
||||
|
@ -1,10 +1,10 @@
|
||||
/* $FreeBSD$ */
|
||||
/* ??? */
|
||||
|
||||
/*
|
||||
* THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT.
|
||||
*
|
||||
* generated from:
|
||||
* FreeBSD: src/sys/dev/usb/usbdevs,v 1.372 2008/09/19 09:04:06 kevlo Exp
|
||||
* FreeBSD: src/sys/dev/usb/usbdevs,v 1.381 2008/11/02 03:00:36 imp Exp
|
||||
*/
|
||||
/* $NetBSD: usbdevs,v 1.392 2004/12/29 08:38:44 imp Exp $ */
|
||||
|
||||
@ -3100,6 +3100,12 @@ const struct usb_knowndev usb_knowndevs[] = {
|
||||
"Hewlett Packard",
|
||||
"Photosmart P1100",
|
||||
},
|
||||
{
|
||||
USB_VENDOR_HP, USB_PRODUCT_HP_OJ4215,
|
||||
0,
|
||||
"Hewlett Packard",
|
||||
"OfficeJet 4215",
|
||||
},
|
||||
{
|
||||
USB_VENDOR_HP, USB_PRODUCT_HP_HN210E,
|
||||
0,
|
||||
@ -3137,10 +3143,10 @@ const struct usb_knowndev usb_knowndevs[] = {
|
||||
"Huawei Mobile",
|
||||
},
|
||||
{
|
||||
USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_E270,
|
||||
USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_E220,
|
||||
0,
|
||||
"Huawei Technologies",
|
||||
"Huawei HSPA modem",
|
||||
"Huawei HSDPA modem",
|
||||
},
|
||||
{
|
||||
USB_VENDOR_HUAWEI3COM, USB_PRODUCT_HUAWEI3COM_WUB320G,
|
||||
@ -4775,7 +4781,7 @@ const struct usb_knowndev usb_knowndevs[] = {
|
||||
"Merlin U727 CDMA",
|
||||
},
|
||||
{
|
||||
USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_U950D,
|
||||
USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_MC950D,
|
||||
0,
|
||||
"Novatel Wireless",
|
||||
"Novatel MC950D HSUPA",
|
||||
@ -4822,6 +4828,12 @@ const struct usb_knowndev usb_knowndevs[] = {
|
||||
"OmniVision",
|
||||
"OV511+ Camera",
|
||||
},
|
||||
{
|
||||
USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_SDS_HOTFIND_D,
|
||||
0,
|
||||
"OnSpec",
|
||||
"SDS-infrared.com Hotfind-D Infrared Camera",
|
||||
},
|
||||
{
|
||||
USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_MDCFE_B_CF_READER,
|
||||
0,
|
||||
@ -4906,6 +4918,12 @@ const struct usb_knowndev usb_knowndevs[] = {
|
||||
"Option N.V:",
|
||||
"GlobeTrotter Max 3.6 Modem",
|
||||
},
|
||||
{
|
||||
USB_VENDOR_OPTION, USB_PRODUCT_OPTION_GTMAXHSUPA,
|
||||
0,
|
||||
"Option N.V:",
|
||||
"GlobeTrotter HSUPA",
|
||||
},
|
||||
{
|
||||
USB_VENDOR_OQO, USB_PRODUCT_OQO_WIFI01,
|
||||
0,
|
||||
@ -5428,6 +5446,12 @@ const struct usb_knowndev usb_knowndevs[] = {
|
||||
"Qualcomm, Incorporated",
|
||||
"CDMA Technologies MSM modem",
|
||||
},
|
||||
{
|
||||
USB_VENDOR_QUALCOMMINC, USB_PRODUCT_QUALCOMMINC_ZTE_STOR,
|
||||
0,
|
||||
"Qualcomm, Incorporated",
|
||||
"USB ZTE Storage",
|
||||
},
|
||||
{
|
||||
USB_VENDOR_QTRONIX, USB_PRODUCT_QTRONIX_980N,
|
||||
0,
|
||||
@ -6388,6 +6412,12 @@ const struct usb_knowndev usb_knowndevs[] = {
|
||||
"Sony",
|
||||
"Sony Clie tj37",
|
||||
},
|
||||
{
|
||||
USB_VENDOR_SONY, USB_PRODUCT_SONY_RF_RECEIVER,
|
||||
0,
|
||||
"Sony",
|
||||
"Sony RF mouse/kbd Receiver VGP-WRC1",
|
||||
},
|
||||
{
|
||||
USB_VENDOR_SONYERICSSON, USB_PRODUCT_SONYERICSSON_DCU10,
|
||||
0,
|
||||
|
@ -31,6 +31,11 @@
|
||||
|
||||
#include <sys/ioccom.h>
|
||||
|
||||
/* Building "kdump" depends on these includes */
|
||||
|
||||
#include <dev/usb2/include/usb2_endian.h>
|
||||
#include <dev/usb2/include/usb2_standard.h>
|
||||
|
||||
#define USB_DEVICE_NAME "usb"
|
||||
#define USB_GENERIC_NAME "ugen"
|
||||
|
||||
|
@ -273,26 +273,6 @@ static const struct usb2_device_id ubsa_devs[] = {
|
||||
{USB_VPI(USB_VENDOR_GOHUBS, USB_PRODUCT_GOHUBS_GOCOM232, 0)},
|
||||
/* Peracom */
|
||||
{USB_VPI(USB_VENDOR_PERACOM, USB_PRODUCT_PERACOM_SERIAL1, 0)},
|
||||
/* Novatel Wireless Merlin cards */
|
||||
{USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_U740, 0)},
|
||||
/* Dell version of the above */
|
||||
{USB_VPI(USB_VENDOR_DELL, USB_PRODUCT_DELL_U740, 0)},
|
||||
/* Novatel Wireless Merlin v740 */
|
||||
{USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_V740, 0)},
|
||||
/* Option Vodafone MC3G */
|
||||
{USB_VPI(USB_VENDOR_OPTION, USB_PRODUCT_OPTION_VODAFONEMC3G, 0)},
|
||||
/* Option GlobeTrotter 3G */
|
||||
{USB_VPI(USB_VENDOR_OPTION, USB_PRODUCT_OPTION_GT3G, 0)},
|
||||
/* Option GlobeTrotter 3G+ */
|
||||
{USB_VPI(USB_VENDOR_OPTION, USB_PRODUCT_OPTION_GT3GPLUS, 0)},
|
||||
/* Option GlobeTrotter Max 3.6 */
|
||||
{USB_VPI(USB_VENDOR_OPTION, USB_PRODUCT_OPTION_GTMAX36, 0)},
|
||||
/* Option GlobeTrotter 3G QUAD */
|
||||
{USB_VPI(USB_VENDOR_OPTION, USB_PRODUCT_OPTION_GT3GQUAD, 0)},
|
||||
/* Sierra Wireless LENOVO UMTS card */
|
||||
{USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8755_3, 0)},
|
||||
/* Qualcomm, Inc. ZTE CDMA */
|
||||
{USB_VPI(USB_VENDOR_QUALCOMMINC, USB_PRODUCT_QUALCOMMINC_CDMA_MSM, 0)},
|
||||
};
|
||||
|
||||
static device_method_t ubsa_methods[] = {
|
||||
|
@ -178,7 +178,7 @@ static const struct usb2_device_id ugensa_devs[] = {
|
||||
{USB_VPI(USB_VENDOR_CMOTECH, USB_PRODUCT_CMOTECH_CDMA_MODEM1, 0)},
|
||||
{USB_VPI(USB_VENDOR_KYOCERA2, USB_PRODUCT_KYOCERA2_CDMA_MSM_K, 0)},
|
||||
{USB_VPI(USB_VENDOR_HP, USB_PRODUCT_HP_49GPLUS, 0)},
|
||||
{USB_VPI(USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_E270, 0)},
|
||||
/* {USB_VPI(USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_E270, 0)}, */
|
||||
{USB_VPI(USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_MOBILE, 0)},
|
||||
{USB_VPI(USB_VENDOR_MERLIN, USB_PRODUCT_MERLIN_V620, 0)},
|
||||
{USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_CDMA_MODEM, 0)},
|
||||
@ -187,7 +187,7 @@ static const struct usb2_device_id ugensa_devs[] = {
|
||||
{USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_U727, 0)},
|
||||
{USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_U740, 0)},
|
||||
{USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_U740_2, 0)},
|
||||
{USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_U950D, 0)},
|
||||
/* {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_U950D, 0)}, */
|
||||
{USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_V620, 0)},
|
||||
{USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_V640, 0)},
|
||||
{USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_V720, 0)},
|
||||
|
@ -3049,9 +3049,6 @@ uaudio_mixer_signext(uint8_t type, int val)
|
||||
static int
|
||||
uaudio_mixer_bsd2value(struct uaudio_mixer_node *mc, int32_t val)
|
||||
{
|
||||
DPRINTFN(6, "type=%03x val=%d min=%d max=%d ",
|
||||
mc->type, val, mc->minval, mc->maxval);
|
||||
|
||||
if (mc->type == MIX_ON_OFF) {
|
||||
val = (val != 0);
|
||||
} else if (mc->type == MIX_SELECTOR) {
|
||||
@ -3063,7 +3060,8 @@ uaudio_mixer_bsd2value(struct uaudio_mixer_node *mc, int32_t val)
|
||||
val = (((val + (mc->delta / 2)) * mc->mul) / 255) + mc->minval;
|
||||
}
|
||||
|
||||
DPRINTFN(6, "val=%d\n", val);
|
||||
DPRINTFN(6, "type=0x%03x val=%d min=%d max=%d val=%d\n",
|
||||
mc->type, val, mc->minval, mc->maxval, val);
|
||||
return (val);
|
||||
}
|
||||
|
||||
|
@ -636,6 +636,10 @@ static const struct umass_devdescr umass_devdescr[] = {
|
||||
UMASS_PROTO_SCSI,
|
||||
NO_GETMAXLUN
|
||||
},
|
||||
{ USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_SDS_HOTFIND_D, RID_WILDCARD,
|
||||
UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
|
||||
NO_GETMAXLUN | NO_SYNCHRONIZE_CACHE
|
||||
},
|
||||
{USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_CFMS_RW, RID_WILDCARD,
|
||||
UMASS_PROTO_SCSI,
|
||||
NO_QUIRKS
|
||||
|
@ -49,7 +49,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <dev/usb2/include/usb2_mfunc.h>
|
||||
#include <dev/usb2/include/usb2_error.h>
|
||||
#include <dev/usb2/include/usb2_ioctl.h>
|
||||
#include <dev/usb2/include/urio2_ioctl.h>
|
||||
#include <dev/usb/rio500_usb.h>
|
||||
|
||||
#define USB_DEBUG_VAR urio_debug
|
||||
|
||||
|
@ -182,6 +182,7 @@ SUBDIR= ${_ac} \
|
||||
tzsetup \
|
||||
ugidfw \
|
||||
${_usbdevs} \
|
||||
${_usbconfig} \
|
||||
${_vidcontrol} \
|
||||
vipw \
|
||||
watch \
|
||||
@ -402,6 +403,7 @@ _crunch= crunch
|
||||
|
||||
.if ${MK_USB} != "no"
|
||||
_usbdevs= usbdevs
|
||||
_usbconfig= usbconfig
|
||||
.endif
|
||||
|
||||
.if ${MK_WIRELESS} != "no"
|
||||
|
@ -96,9 +96,6 @@ static void
|
||||
dump_field(struct libusb20_device *pdev, const char *plevel,
|
||||
const char *field, uint32_t value)
|
||||
{
|
||||
struct LIBUSB20_CONTROL_SETUP_DECODED req;
|
||||
uint16_t lang_id;
|
||||
uint8_t index;
|
||||
uint8_t temp_string[256];
|
||||
|
||||
printf("%s%s = 0x%04x ", plevel, field, value);
|
||||
@ -108,64 +105,15 @@ dump_field(struct libusb20_device *pdev, const char *plevel,
|
||||
return;
|
||||
}
|
||||
if (value == 0) {
|
||||
printf(" <no string> \n");
|
||||
printf(" <no string>\n");
|
||||
return;
|
||||
}
|
||||
LIBUSB20_INIT(LIBUSB20_CONTROL_SETUP, &req);
|
||||
|
||||
lang_id = 0;
|
||||
index = 0;
|
||||
|
||||
req.bmRequestType =
|
||||
LIBUSB20_REQUEST_TYPE_STANDARD |
|
||||
LIBUSB20_RECIPIENT_DEVICE |
|
||||
LIBUSB20_ENDPOINT_IN;
|
||||
req.bRequest = LIBUSB20_REQUEST_GET_DESCRIPTOR;
|
||||
req.wValue = (256 * LIBUSB20_DT_STRING) | index;
|
||||
req.wIndex = lang_id;
|
||||
req.wLength = 4; /* bytes */
|
||||
|
||||
if (libusb20_dev_request_sync(pdev, &req,
|
||||
temp_string, NULL, 1000, 0)) {
|
||||
goto done;
|
||||
if (libusb20_dev_req_string_simple_sync(pdev, value,
|
||||
temp_string, sizeof(temp_string))) {
|
||||
printf(" <retrieving string failed>\n");
|
||||
return;
|
||||
}
|
||||
lang_id = temp_string[2] | (temp_string[3] << 8);
|
||||
|
||||
printf(" LangId:0x%04x <", lang_id);
|
||||
|
||||
index = value;
|
||||
|
||||
req.wValue = (256 * LIBUSB20_DT_STRING) | index;
|
||||
req.wIndex = lang_id;
|
||||
req.wLength = 4; /* bytes */
|
||||
|
||||
if (libusb20_dev_request_sync(pdev, &req,
|
||||
temp_string, NULL, 1000, 0)) {
|
||||
printf("ERROR>\n");
|
||||
goto done;
|
||||
}
|
||||
req.wValue = (256 * LIBUSB20_DT_STRING) | index;
|
||||
req.wIndex = lang_id;
|
||||
req.wLength = temp_string[0]; /* bytes */
|
||||
|
||||
if (libusb20_dev_request_sync(pdev, &req,
|
||||
temp_string, NULL, 1000, 0)) {
|
||||
printf("ERROR>\n");
|
||||
goto done;
|
||||
}
|
||||
req.wLength /= 2;
|
||||
|
||||
for (index = 1; index != req.wLength; index++) {
|
||||
if (isprint(temp_string[(2 * index) + 0])) {
|
||||
printf("%c", temp_string[(2 * index) + 0]);
|
||||
} else if (isprint(temp_string[(2 * index) + 1])) {
|
||||
printf("%c", temp_string[(2 * index) + 1]);
|
||||
} else {
|
||||
printf("?");
|
||||
}
|
||||
}
|
||||
printf(">\n");
|
||||
done:
|
||||
printf(" <%s>\n", temp_string);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -244,7 +192,7 @@ dump_be_quirk_names(struct libusb20_backend *pbe)
|
||||
{
|
||||
struct libusb20_quirk q;
|
||||
uint16_t x;
|
||||
int err;
|
||||
int error;
|
||||
|
||||
memset(&q, 0, sizeof(q));
|
||||
|
||||
@ -252,8 +200,8 @@ dump_be_quirk_names(struct libusb20_backend *pbe)
|
||||
|
||||
for (x = 0; x != 0xFFFF; x++) {
|
||||
|
||||
err = libusb20_be_get_quirk_name(pbe, x, &q);
|
||||
if (err) {
|
||||
error = libusb20_be_get_quirk_name(pbe, x, &q);
|
||||
if (error) {
|
||||
if (x == 0) {
|
||||
printf("No quirk names - maybe the USB quirk "
|
||||
"module has not been loaded.\n");
|
||||
@ -272,7 +220,7 @@ dump_be_dev_quirks(struct libusb20_backend *pbe)
|
||||
{
|
||||
struct libusb20_quirk q;
|
||||
uint16_t x;
|
||||
int err;
|
||||
int error;
|
||||
|
||||
memset(&q, 0, sizeof(q));
|
||||
|
||||
@ -280,8 +228,8 @@ dump_be_dev_quirks(struct libusb20_backend *pbe)
|
||||
|
||||
for (x = 0; x != 0xFFFF; x++) {
|
||||
|
||||
err = libusb20_be_get_dev_quirk(pbe, x, &q);
|
||||
if (err) {
|
||||
error = libusb20_be_get_dev_quirk(pbe, x, &q);
|
||||
if (error) {
|
||||
if (x == 0) {
|
||||
printf("No device quirks - maybe the USB quirk "
|
||||
"module has not been loaded.\n");
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include <libusb20_desc.h>
|
||||
#include <libusb20.h>
|
||||
@ -40,10 +41,12 @@
|
||||
|
||||
struct options {
|
||||
const char *quirkname;
|
||||
void *buffer;
|
||||
gid_t gid;
|
||||
uid_t uid;
|
||||
mode_t mode;
|
||||
uint32_t got_any;
|
||||
struct LIBUSB20_CONTROL_SETUP_DECODED setup;
|
||||
uint16_t bus;
|
||||
uint16_t addr;
|
||||
uint16_t iface;
|
||||
@ -51,6 +54,7 @@ struct options {
|
||||
uint16_t pid;
|
||||
uint16_t lo_rev; /* inclusive */
|
||||
uint16_t hi_rev; /* inclusive */
|
||||
uint8_t string_index;
|
||||
uint8_t config_index;
|
||||
uint8_t alt_index;
|
||||
uint8_t got_list:1;
|
||||
@ -76,6 +80,8 @@ struct options {
|
||||
uint8_t got_dump_access:1;
|
||||
uint8_t got_remove_device_quirk:1;
|
||||
uint8_t got_add_device_quirk:1;
|
||||
uint8_t got_dump_string:1;
|
||||
uint8_t got_do_request:1;
|
||||
};
|
||||
|
||||
struct token {
|
||||
@ -99,6 +105,7 @@ enum {
|
||||
T_DUMP_DEVICE_DESC,
|
||||
T_DUMP_CURR_CONFIG_DESC,
|
||||
T_DUMP_ALL_CONFIG_DESC,
|
||||
T_DUMP_STRING,
|
||||
T_DUMP_ACCESS,
|
||||
T_DUMP_INFO,
|
||||
T_SUSPEND,
|
||||
@ -108,6 +115,7 @@ enum {
|
||||
T_POWER_ON,
|
||||
T_RESET,
|
||||
T_LIST,
|
||||
T_DO_REQUEST,
|
||||
};
|
||||
|
||||
static struct options options;
|
||||
@ -127,6 +135,7 @@ static const struct token token[] = {
|
||||
{"dump_device_desc", T_DUMP_DEVICE_DESC, 0},
|
||||
{"dump_curr_config_desc", T_DUMP_CURR_CONFIG_DESC, 0},
|
||||
{"dump_all_config_desc", T_DUMP_ALL_CONFIG_DESC, 0},
|
||||
{"dump_string", T_DUMP_STRING, 1},
|
||||
{"dump_access", T_DUMP_ACCESS, 0},
|
||||
{"dump_info", T_DUMP_INFO, 0},
|
||||
{"suspend", T_SUSPEND, 0},
|
||||
@ -136,6 +145,7 @@ static const struct token token[] = {
|
||||
{"power_on", T_POWER_ON, 0},
|
||||
{"reset", T_RESET, 0},
|
||||
{"list", T_LIST, 0},
|
||||
{"do_request", T_DO_REQUEST, 5},
|
||||
};
|
||||
|
||||
static void
|
||||
@ -144,7 +154,7 @@ be_dev_remove_quirk(struct libusb20_backend *pbe,
|
||||
const char *str)
|
||||
{
|
||||
struct libusb20_quirk q;
|
||||
int err;
|
||||
int error;
|
||||
|
||||
memset(&q, 0, sizeof(q));
|
||||
|
||||
@ -154,8 +164,8 @@ be_dev_remove_quirk(struct libusb20_backend *pbe,
|
||||
q.bcdDeviceHigh = hirev;
|
||||
strlcpy(q.quirkname, str, sizeof(q.quirkname));
|
||||
|
||||
err = libusb20_be_remove_dev_quirk(pbe, &q);
|
||||
if (err) {
|
||||
error = libusb20_be_remove_dev_quirk(pbe, &q);
|
||||
if (error) {
|
||||
printf("Removing quirk '%s' failed, continuing.\n", str);
|
||||
}
|
||||
return;
|
||||
@ -167,7 +177,7 @@ be_dev_add_quirk(struct libusb20_backend *pbe,
|
||||
const char *str)
|
||||
{
|
||||
struct libusb20_quirk q;
|
||||
int err;
|
||||
int error;
|
||||
|
||||
memset(&q, 0, sizeof(q));
|
||||
|
||||
@ -177,8 +187,8 @@ be_dev_add_quirk(struct libusb20_backend *pbe,
|
||||
q.bcdDeviceHigh = hirev;
|
||||
strlcpy(q.quirkname, str, sizeof(q.quirkname));
|
||||
|
||||
err = libusb20_be_add_dev_quirk(pbe, &q);
|
||||
if (err) {
|
||||
error = libusb20_be_add_dev_quirk(pbe, &q);
|
||||
if (error) {
|
||||
printf("Adding quirk '%s' failed, continuing.\n", str);
|
||||
}
|
||||
return;
|
||||
@ -192,7 +202,7 @@ get_token(const char *str, uint8_t narg)
|
||||
for (n = 0; n != (sizeof(token) / sizeof(token[0])); n++) {
|
||||
if (strcasecmp(str, token[n].name) == 0) {
|
||||
if (token[n].narg > narg) {
|
||||
/* to little arguments */
|
||||
/* too few arguments */
|
||||
break;
|
||||
}
|
||||
return (token[n].value);
|
||||
@ -266,8 +276,8 @@ usage(void)
|
||||
"usbconfig - configure the USB subsystem" "\n"
|
||||
"usage: usbconfig -u <busnum> -a <devaddr> -i <ifaceindex> [cmds...]" "\n"
|
||||
"commands:" "\n"
|
||||
" set_config <num>" "\n"
|
||||
" set_alt <altno>" "\n"
|
||||
" set_config <cfg_index>" "\n"
|
||||
" set_alt <alt_index>" "\n"
|
||||
" set_owner <user:group>" "\n"
|
||||
" set_perm <mode>" "\n"
|
||||
" add_dev_quirk_vplh <vid> <pid> <lo_rev> <hi_rev> <quirk>" "\n"
|
||||
@ -277,6 +287,7 @@ usage(void)
|
||||
" dump_device_desc" "\n"
|
||||
" dump_curr_config_desc" "\n"
|
||||
" dump_all_config_desc" "\n"
|
||||
" dump_string <index>" "\n"
|
||||
" dump_access" "\n"
|
||||
" dump_info" "\n"
|
||||
" suspend" "\n"
|
||||
@ -286,6 +297,7 @@ usage(void)
|
||||
" power_on" "\n"
|
||||
" reset" "\n"
|
||||
" list" "\n"
|
||||
" do_request <bmReqTyp> <bReq> <wVal> <wIdx> <wLen> <data...>" "\n"
|
||||
);
|
||||
exit(1);
|
||||
}
|
||||
@ -293,6 +305,8 @@ usage(void)
|
||||
static void
|
||||
reset_options(struct options *opt)
|
||||
{
|
||||
if (opt->buffer)
|
||||
free(opt->buffer);
|
||||
memset(opt, 0, sizeof(*opt));
|
||||
return;
|
||||
}
|
||||
@ -418,6 +432,54 @@ flush_command(struct libusb20_backend *pbe, struct options *opt)
|
||||
if (libusb20_dev_open(pdev, 0)) {
|
||||
err(1, "could not open device");
|
||||
}
|
||||
if (opt->got_dump_string) {
|
||||
char *pbuf;
|
||||
|
||||
pbuf = malloc(256);
|
||||
if (pbuf == NULL) {
|
||||
err(1, "out of memory");
|
||||
}
|
||||
if (libusb20_dev_req_string_simple_sync(pdev,
|
||||
opt->string_index, pbuf, 256)) {
|
||||
printf("STRING_0x%02x = <read error>\n",
|
||||
opt->string_index);
|
||||
} else {
|
||||
printf("STRING_0x%02x = <%s>\n",
|
||||
opt->string_index, pbuf);
|
||||
}
|
||||
free(pbuf);
|
||||
}
|
||||
if (opt->got_do_request) {
|
||||
uint16_t actlen;
|
||||
uint16_t t;
|
||||
|
||||
if (libusb20_dev_request_sync(pdev, &opt->setup,
|
||||
opt->buffer, &actlen, 5000 /* 5 seconds */ , 0)) {
|
||||
printf("REQUEST = <ERROR>\n");
|
||||
} else if (!(opt->setup.bmRequestType &
|
||||
LIBUSB20_ENDPOINT_IN)) {
|
||||
printf("REQUEST = <OK>\n");
|
||||
} else {
|
||||
t = actlen;
|
||||
printf("REQUEST = <");
|
||||
for (t = 0; t != actlen; t++) {
|
||||
printf("0x%02x%s",
|
||||
((uint8_t *)opt->buffer)[t],
|
||||
(t == (actlen - 1)) ? "" : " ");
|
||||
}
|
||||
printf("><");
|
||||
for (t = 0; t != actlen; t++) {
|
||||
char c;
|
||||
|
||||
c = ((uint8_t *)opt->buffer)[t];
|
||||
if ((c != '<') &&
|
||||
(c != '>') && isprint(c)) {
|
||||
putchar(c);
|
||||
}
|
||||
}
|
||||
printf(">\n");
|
||||
}
|
||||
}
|
||||
if (opt->got_set_config) {
|
||||
if (libusb20_dev_set_config_index(pdev,
|
||||
opt->config_index)) {
|
||||
@ -425,7 +487,8 @@ flush_command(struct libusb20_backend *pbe, struct options *opt)
|
||||
}
|
||||
}
|
||||
if (opt->got_set_alt) {
|
||||
if (libusb20_dev_set_alt_index(pdev, opt->iface, opt->alt_index)) {
|
||||
if (libusb20_dev_set_alt_index(pdev, opt->iface,
|
||||
opt->alt_index)) {
|
||||
err(1, "could not set alternate setting");
|
||||
}
|
||||
}
|
||||
@ -435,27 +498,32 @@ flush_command(struct libusb20_backend *pbe, struct options *opt)
|
||||
}
|
||||
}
|
||||
if (opt->got_suspend) {
|
||||
if (libusb20_dev_set_power_mode(pdev, LIBUSB20_POWER_SUSPEND)) {
|
||||
if (libusb20_dev_set_power_mode(pdev,
|
||||
LIBUSB20_POWER_SUSPEND)) {
|
||||
err(1, "could not set suspend");
|
||||
}
|
||||
}
|
||||
if (opt->got_resume) {
|
||||
if (libusb20_dev_set_power_mode(pdev, LIBUSB20_POWER_RESUME)) {
|
||||
if (libusb20_dev_set_power_mode(pdev,
|
||||
LIBUSB20_POWER_RESUME)) {
|
||||
err(1, "could not set resume");
|
||||
}
|
||||
}
|
||||
if (opt->got_power_off) {
|
||||
if (libusb20_dev_set_power_mode(pdev, LIBUSB20_POWER_OFF)) {
|
||||
if (libusb20_dev_set_power_mode(pdev,
|
||||
LIBUSB20_POWER_OFF)) {
|
||||
err(1, "could not set power OFF");
|
||||
}
|
||||
}
|
||||
if (opt->got_power_save) {
|
||||
if (libusb20_dev_set_power_mode(pdev, LIBUSB20_POWER_SAVE)) {
|
||||
if (libusb20_dev_set_power_mode(pdev,
|
||||
LIBUSB20_POWER_SAVE)) {
|
||||
err(1, "could not set power SAVE");
|
||||
}
|
||||
}
|
||||
if (opt->got_power_on) {
|
||||
if (libusb20_dev_set_power_mode(pdev, LIBUSB20_POWER_ON)) {
|
||||
if (libusb20_dev_set_power_mode(pdev,
|
||||
LIBUSB20_POWER_ON)) {
|
||||
err(1, "could not set power ON");
|
||||
}
|
||||
}
|
||||
@ -584,13 +652,13 @@ main(int argc, char **argv)
|
||||
n++;
|
||||
break;
|
||||
case T_SET_CONFIG:
|
||||
opt->config_index = num_id(argv[n + 1], "confindex");
|
||||
opt->config_index = num_id(argv[n + 1], "cfg_index");
|
||||
opt->got_set_config = 1;
|
||||
opt->got_any++;
|
||||
n++;
|
||||
break;
|
||||
case T_SET_ALT:
|
||||
opt->alt_index = num_id(argv[n + 1], "confindex");
|
||||
opt->alt_index = num_id(argv[n + 1], "cfg_index");
|
||||
opt->got_set_alt = 1;
|
||||
opt->got_any++;
|
||||
n++;
|
||||
@ -630,9 +698,18 @@ main(int argc, char **argv)
|
||||
opt->got_dump_info = 1;
|
||||
opt->got_any++;
|
||||
break;
|
||||
case T_DUMP_STRING:
|
||||
if (opt->got_dump_string) {
|
||||
flush_command(pbe, opt);
|
||||
}
|
||||
opt->string_index = num_id(argv[n + 1], "str_index");
|
||||
opt->got_dump_string = 1;
|
||||
opt->got_any++;
|
||||
n++;
|
||||
break;
|
||||
case T_DUMP_ACCESS:
|
||||
opt->got_dump_access = 1;
|
||||
opt->got_any++;
|
||||
opt->got_any += 2;
|
||||
break;
|
||||
case T_SUSPEND:
|
||||
opt->got_suspend = 1;
|
||||
@ -662,6 +739,41 @@ main(int argc, char **argv)
|
||||
opt->got_list = 1;
|
||||
opt->got_any++;
|
||||
break;
|
||||
case T_DO_REQUEST:
|
||||
if (opt->got_do_request) {
|
||||
flush_command(pbe, opt);
|
||||
}
|
||||
LIBUSB20_INIT(LIBUSB20_CONTROL_SETUP, &opt->setup);
|
||||
opt->setup.bmRequestType = num_id(argv[n + 1], "bmReqTyp");
|
||||
opt->setup.bRequest = num_id(argv[n + 2], "bReq");
|
||||
opt->setup.wValue = num_id(argv[n + 3], "wVal");
|
||||
opt->setup.wIndex = num_id(argv[n + 4], "wIndex");
|
||||
opt->setup.wLength = num_id(argv[n + 5], "wLen");
|
||||
if (opt->setup.wLength != 0) {
|
||||
opt->buffer = malloc(opt->setup.wLength);
|
||||
} else {
|
||||
opt->buffer = NULL;
|
||||
}
|
||||
|
||||
n += 5;
|
||||
|
||||
if (!(opt->setup.bmRequestType &
|
||||
LIBUSB20_ENDPOINT_IN)) {
|
||||
/* copy in data */
|
||||
t = (argc - n - 1);
|
||||
if (t < opt->setup.wLength) {
|
||||
err(1, "request data missing");
|
||||
}
|
||||
t = opt->setup.wLength;
|
||||
while (t--) {
|
||||
((uint8_t *)opt->buffer)[t] =
|
||||
num_id(argv[n + t + 1], "req_data");
|
||||
}
|
||||
n += opt->setup.wLength;
|
||||
}
|
||||
opt->got_do_request = 1;
|
||||
opt->got_any++;
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user