1
0
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:
Alfred Perlstein 2008-11-19 08:56:35 +00:00
parent 202f306c24
commit 6f0e1ffd07
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=185087
43 changed files with 1021 additions and 3515 deletions

View File

@ -120,6 +120,10 @@
..
usb
..
usb2
include
..
..
utopia
..
vkbd

View File

@ -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

View File

@ -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>

View File

@ -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.
.

View File

@ -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

View File

@ -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);

View File

@ -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 */

View File

@ -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);

View File

@ -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 */

View File

@ -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 {

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -32,7 +32,7 @@
struct RioCommand
{
u_int16_t length;
uint16_t length;
int request;
int requesttype;
int value;

View File

@ -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);

View File

@ -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 */

View File

@ -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 */

View File

@ -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);
}

View File

@ -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++;
}

View File

@ -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 */

View File

@ -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)
{

View File

@ -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);

View File

@ -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;
}

View File

@ -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);

View File

@ -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_ */

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 */

View File

@ -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,

View File

@ -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"

View File

@ -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[] = {

View File

@ -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)},

View File

@ -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);
}

View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -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");

View File

@ -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;