exit 1
fi
-# run autotools on haiku package
-cd libusb/os/haiku || exit 1
-$LIBTOOLIZE --copy --force || exit 1
-aclocal || exit 1
-autoconf || exit 1
-automake -a -c || exit 1
-cd ../../..
-
$LIBTOOLIZE --copy --force || exit 1
aclocal || exit 1
autoheader || exit 1
AC_PREREQ([2.50])
AC_PROG_CC
+AC_PROG_CXX
LT_INIT
LT_LANG([Windows Resource])
AC_C_INLINE
;;
*-haiku*)
AC_MSG_RESULT([Haiku])
- AC_CONFIG_SUBDIRS([libusb/os/haiku])
backend="haiku"
threads="posix"
;;
lib_LTLIBRARIES = libusb-1.0.la
-POSIX_POLL_SRC = os/poll_posix.c
-LINUX_USBFS_SRC = os/linux_usbfs.c
-DARWIN_USB_SRC = os/darwin_usb.c
+POSIX_POLL_SRC = os/poll_posix.h os/poll_posix.c
+POSIX_THREADS_SRC = os/threads_posix.h os/threads_posix.c
+WINDOWS_POLL_SRC = os/poll_windows.h os/poll_windows.c
+WINDOWS_THREADS_SRC = os/threads_windows.h os/threads_windows.c
+LINUX_USBFS_SRC = os/linux_usbfs.h os/linux_usbfs.c
+DARWIN_USB_SRC = os/darwin_usb.h os/darwin_usb.c
OPENBSD_USB_SRC = os/openbsd_usb.c
NETBSD_USB_SRC = os/netbsd_usb.c
-WINDOWS_USB_SRC = os/poll_windows.c os/windows_usb.c libusb-1.0.rc libusb-1.0.def
-WINCE_USB_SRC = os/wince_usb.c os/wince_usb.h
-
-DIST_SUBDIRS =
-
-EXTRA_DIST = $(LINUX_USBFS_SRC) $(DARWIN_USB_SRC) $(OPENBSD_USB_SRC) \
- $(NETBSD_USB_SRC) $(WINDOWS_USB_SRC) $(WINCE_USB_SRC) \
- $(POSIX_POLL_SRC) \
- os/threads_posix.c os/threads_windows.c \
+WINDOWS_USB_SRC = os/windows_common.h os/windows_usb.h os/windows_usb.c libusb-1.0.rc libusb-1.0.def
+WINCE_USB_SRC = os/wince_usb.h os/wince_usb.c
+HAIKU_USB_SRC = os/haiku_usb.h os/haiku_usb_backend.cpp \
+ os/haiku_usb_raw.h os/haiku_usb_raw.cpp os/haiku_pollfs.cpp
+
+EXTRA_DIST = $(POSIX_POLL_SRC) $(POSIX_THREADS_SRC) \
+ $(WINDOWS_POLL_SRC) $(WINDOWS_THREADS_SRC) \
+ $(LINUX_USBFS_SRC) $(DARWIN_USB_SRC) \
+ $(OPENBSD_USB_SRC) $(NETBSD_USB_SRC) \
+ $(WINDOWS_USB_SRC) $(WINCE_USB_SRC) \
+ $(HAIKU_USB_SRC) \
os/linux_udev.c os/linux_netlink.c
-dist-hook:
- cp -r os/haiku $(distdir)/os/haiku
- rm -rf $(distdir)/os/haiku/autom4te.cache
-
if OS_LINUX
if USE_UDEV
-OS_SRC = $(LINUX_USBFS_SRC) $(POSIX_POLL_SRC) \
- os/linux_udev.c
+OS_SRC = $(LINUX_USBFS_SRC) os/linux_udev.c
else
-OS_SRC = $(LINUX_USBFS_SRC) $(POSIX_POLL_SRC) \
- os/linux_netlink.c
+OS_SRC = $(LINUX_USBFS_SRC) os/linux_netlink.c
endif
endif
if OS_DARWIN
-OS_SRC = $(DARWIN_USB_SRC) $(POSIX_POLL_SRC)
+OS_SRC = $(DARWIN_USB_SRC)
AM_CFLAGS_EXT = -no-cpp-precomp
endif
if OS_OPENBSD
-OS_SRC = $(OPENBSD_USB_SRC) $(POSIX_POLL_SRC)
+OS_SRC = $(OPENBSD_USB_SRC)
endif
if OS_NETBSD
-OS_SRC = $(NETBSD_USB_SRC) $(POSIX_POLL_SRC)
+OS_SRC = $(NETBSD_USB_SRC)
endif
if OS_HAIKU
-OS_SRC = $(POSIX_POLL_SRC)
-SUBDIRS = os/haiku
+noinst_LTLIBRARIES = libusb_haiku.la
+libusb_haiku_la_SOURCES = $(HAIKU_USB_SRC)
+libusb_1_0_la_LIBADD = libusb_haiku.la
endif
if OS_WINDOWS
$(AM_V_GEN)$(DLLTOOL) $(DLLTOOLFLAGS) --kill-at --input-def $(srcdir)/libusb-1.0.def --dllname $@ --output-lib .libs/$@.a
endif
+if OS_WINDOWS
+POLL_SRC = $(WINDOWS_POLL_SRC)
+else
+POLL_SRC = $(POSIX_POLL_SRC)
+endif
+
if THREADS_POSIX
-THREADS_SRC = os/threads_posix.h os/threads_posix.c
+THREADS_SRC = $(POSIX_THREADS_SRC)
else
-THREADS_SRC = os/threads_windows.h os/threads_windows.c
+THREADS_SRC = $(WINDOWS_THREADS_SRC)
endif
libusb_1_0_la_CFLAGS = $(AM_CFLAGS)
libusb_1_0_la_LDFLAGS = $(LTLDFLAGS)
-libusb_1_0_la_SOURCES = libusbi.h core.c descriptor.c io.c strerror.c sync.c \
- os/linux_usbfs.h os/darwin_usb.h os/windows_usb.h os/windows_common.h \
- hotplug.h hotplug.c $(THREADS_SRC) $(OS_SRC) \
- os/poll_posix.h os/poll_windows.h
-
-if OS_HAIKU
-libusb_1_0_la_LIBADD = os/haiku/libhaikuusb.la
-endif
+libusb_1_0_la_SOURCES = libusbi.h libusb.h version.h version_nano.h \
+ core.c descriptor.c hotplug.h hotplug.c io.c strerror.c sync.c \
+ $(POLL_SRC) $(THREADS_SRC) $(OS_SRC)
hdrdir = $(includedir)/libusb-1.0
hdr_HEADERS = libusb.h
+++ /dev/null
-ACLOCAL_AMFLAGS = -I m4
-AUTOMAKE_OPTIONS = subdir-objects
-noinst_LTLIBRARIES = libhaikuusb.la
-libhaikuusb_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(srcdir)/.. -I$(srcdir)/../.. -I$(srcdir)/../../.. -I$(srcdir)/../../../..
-libhaikuusb_la_SOURCES = haiku_usb_raw.cpp haiku_usb_backend.cpp haiku_pollfs.cpp haiku_usb_raw.h haiku_usb.h
+++ /dev/null
-AC_INIT([haikuusb], [1.0])
-AM_INIT_AUTOMAKE([no-define foreign])
-AM_MAINTAINER_MODE
-LT_INIT
-AC_PROG_CXX
-AC_CONFIG_FILES([Makefile])
-AC_CONFIG_MACRO_DIR([m4])
-AC_OUTPUT
+++ /dev/null
-/*
- * Haiku Backend for libusb
- * Copyright © 2014 Akshay Jaggi <akshay1994.leo@gmail.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-
-#include <unistd.h>
-#include <string.h>
-#include <stdlib.h>
-#include <new>
-#include <vector>
-
-#include "haiku_usb.h"
-
-int _errno_to_libusb(int status)
-{
- return status;
-}
-
-USBTransfer::USBTransfer(struct usbi_transfer* itransfer, USBDevice* device)
-{
- fUsbiTransfer=itransfer;
- fLibusbTransfer=USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
- fUSBDevice=device;
- fCancelled=false;
-}
-
-USBTransfer::~USBTransfer()
-{
-}
-
-struct usbi_transfer*
-USBTransfer::UsbiTransfer()
-{
- return fUsbiTransfer;
-}
-
-void
-USBTransfer::SetCancelled()
-{
- fCancelled=true;
-}
-
-bool
-USBTransfer::IsCancelled()
-{
- return fCancelled;
-}
-
-void
-USBTransfer::Do(int fRawFD)
-{
- switch(fLibusbTransfer->type)
- {
- case LIBUSB_TRANSFER_TYPE_CONTROL:
- {
- struct libusb_control_setup* setup=(struct libusb_control_setup*)fLibusbTransfer->buffer;
- usb_raw_command command;
- command.control.request_type=setup->bmRequestType;
- command.control.request=setup->bRequest;
- command.control.value=setup->wValue;
- command.control.index=setup->wIndex;
- command.control.length=setup->wLength;
- command.control.data=fLibusbTransfer->buffer + LIBUSB_CONTROL_SETUP_SIZE;
- if(fCancelled)
- {
- break;
- }
- if(ioctl(fRawFD,B_USB_RAW_COMMAND_CONTROL_TRANSFER,&command,
- sizeof(command)) || command.control.status!=B_USB_RAW_STATUS_SUCCESS) {
- fUsbiTransfer->transferred=-1;
- usbi_err(TRANSFER_CTX(fLibusbTransfer),"failed control transfer");
- break;
- }
- fUsbiTransfer->transferred=command.control.length;
- }
- break;
- case LIBUSB_TRANSFER_TYPE_BULK:
- case LIBUSB_TRANSFER_TYPE_INTERRUPT:
- {
- usb_raw_command command;
- command.transfer.interface=fUSBDevice->EndpointToInterface(fLibusbTransfer->endpoint);
- command.transfer.endpoint=fUSBDevice->EndpointToIndex(fLibusbTransfer->endpoint);
- command.transfer.data=fLibusbTransfer->buffer;
- command.transfer.length=fLibusbTransfer->length;
- if(fCancelled)
- {
- break;
- }
- if(fLibusbTransfer->type==LIBUSB_TRANSFER_TYPE_BULK)
- {
- if(ioctl(fRawFD,B_USB_RAW_COMMAND_BULK_TRANSFER,&command,
- sizeof(command)) || command.transfer.status!=B_USB_RAW_STATUS_SUCCESS) {
- fUsbiTransfer->transferred=-1;
- usbi_err(TRANSFER_CTX(fLibusbTransfer),"failed bulk transfer");
- break;
- }
- }
- else
- {
- if(ioctl(fRawFD,B_USB_RAW_COMMAND_INTERRUPT_TRANSFER,&command,
- sizeof(command)) || command.transfer.status!=B_USB_RAW_STATUS_SUCCESS) {
- fUsbiTransfer->transferred=-1;
- usbi_err(TRANSFER_CTX(fLibusbTransfer),"failed interrupt transfer");
- break;
- }
- }
- fUsbiTransfer->transferred=command.transfer.length;
- }
- break;
- // IsochronousTransfers not tested
- case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
- {
- usb_raw_command command;
- command.isochronous.interface=fUSBDevice->EndpointToInterface(fLibusbTransfer->endpoint);
- command.isochronous.endpoint=fUSBDevice->EndpointToIndex(fLibusbTransfer->endpoint);
- command.isochronous.data=fLibusbTransfer->buffer;
- command.isochronous.length=fLibusbTransfer->length;
- command.isochronous.packet_count=fLibusbTransfer->num_iso_packets;
- int i=0;
- usb_iso_packet_descriptor *packetDescriptors = new usb_iso_packet_descriptor[fLibusbTransfer->num_iso_packets];
- for (i=0; i<fLibusbTransfer->num_iso_packets; i++)
- {
- if((int16)(fLibusbTransfer->iso_packet_desc[i]).length!=(fLibusbTransfer->iso_packet_desc[i]).length)
- {
- fUsbiTransfer->transferred=-1;
- usbi_err(TRANSFER_CTX(fLibusbTransfer),"failed isochronous transfer");
- break;
- }
- packetDescriptors[i].request_length=(int16)(fLibusbTransfer->iso_packet_desc[i]).length;
- }
- if(i<fLibusbTransfer->num_iso_packets)
- {
- break; // TODO Handle this error
- }
- command.isochronous.packet_descriptors=packetDescriptors;
- if(fCancelled)
- {
- break;
- }
- if(ioctl(fRawFD,B_USB_RAW_COMMAND_ISOCHRONOUS_TRANSFER,&command,
- sizeof(command)) || command.isochronous.status!=B_USB_RAW_STATUS_SUCCESS) {
- fUsbiTransfer->transferred=-1;
- usbi_err(TRANSFER_CTX(fLibusbTransfer),"failed isochronous transfer");
- break;
- }
- for (i=0; i<fLibusbTransfer->num_iso_packets; i++)
- {
- (fLibusbTransfer->iso_packet_desc[i]).actual_length=packetDescriptors[i].actual_length;
- switch(packetDescriptors[i].status)
- {
- case B_OK: (fLibusbTransfer->iso_packet_desc[i]).status=LIBUSB_TRANSFER_COMPLETED;
- break;
- default: (fLibusbTransfer->iso_packet_desc[i]).status=LIBUSB_TRANSFER_ERROR;
- break;
- }
- }
- delete[] packetDescriptors;
- // Do we put the length of transfer here, for isochronous transfers?
- fUsbiTransfer->transferred=command.transfer.length;
- }
- break;
- default:
- usbi_err(TRANSFER_CTX(fLibusbTransfer),"Unknown type of transfer");
- }
-}
-
-bool
-USBDeviceHandle::InitCheck()
-{
- return fInitCheck;
-}
-
-status_t
-USBDeviceHandle::TransfersThread(void* self)
-{
- USBDeviceHandle* handle = (USBDeviceHandle*)self;
- handle->TransfersWorker();
- return B_OK;
-}
-
-void
-USBDeviceHandle::TransfersWorker()
-{
- while(true)
- {
- status_t status = acquire_sem(fTransfersSem);
- if(status== B_BAD_SEM_ID)
- break;
- if(status == B_INTERRUPTED)
- continue;
- fTransfersLock.Lock();
- USBTransfer* fPendingTransfer= (USBTransfer*) fTransfers.RemoveItem((int32)0);
- fTransfersLock.Unlock();
- fPendingTransfer->Do(fRawFD);
- usbi_signal_transfer_completion(fPendingTransfer->UsbiTransfer());
- }
-}
-
-status_t
-USBDeviceHandle::SubmitTransfer(struct usbi_transfer* itransfer)
-{
- USBTransfer* transfer = new USBTransfer(itransfer,fUSBDevice);
- *((USBTransfer**)usbi_transfer_get_os_priv(itransfer))=transfer;
- BAutolock locker(fTransfersLock);
- fTransfers.AddItem(transfer);
- release_sem(fTransfersSem);
- return LIBUSB_SUCCESS;
-}
-
-status_t
-USBDeviceHandle::CancelTransfer(USBTransfer* transfer)
-{
- transfer->SetCancelled();
- fTransfersLock.Lock();
- bool removed = fTransfers.RemoveItem(transfer);
- fTransfersLock.Unlock();
- if(removed)
- {
- usbi_signal_transfer_completion(transfer->UsbiTransfer());
- }
- return LIBUSB_SUCCESS;
-}
-
-USBDeviceHandle::USBDeviceHandle(USBDevice* dev)
- :
- fTransfersThread(-1),
- fUSBDevice(dev),
- fClaimedInterfaces(0),
- fInitCheck(false)
-{
- fRawFD=open(dev->Location(), O_RDWR | O_CLOEXEC);
- if(fRawFD < 0)
- {
- usbi_err(NULL,"failed to open device");
- return;
- }
- fTransfersSem = create_sem(0, "Transfers Queue Sem");
- fTransfersThread = spawn_thread(TransfersThread,"Transfer Worker",B_NORMAL_PRIORITY, this);
- resume_thread(fTransfersThread);
- fInitCheck = true;
-}
-
-USBDeviceHandle::~USBDeviceHandle()
-{
- if(fRawFD>0)
- close(fRawFD);
- for(int i=0; i<32; i++)
- {
- if(fClaimedInterfaces&(1<<i))
- ReleaseInterface(i);
- }
- delete_sem(fTransfersSem);
- if(fTransfersThread>0)
- wait_for_thread(fTransfersThread, NULL);
-}
-
-int
-USBDeviceHandle::ClaimInterface(int inumber)
-{
- int status=fUSBDevice->ClaimInterface(inumber);
- if(status==LIBUSB_SUCCESS)
- {
- fClaimedInterfaces|=(1<<inumber);
- }
- return status;
-}
-
-int
-USBDeviceHandle::ReleaseInterface(int inumber)
-{
- fUSBDevice->ReleaseInterface(inumber);
- fClaimedInterfaces&=(!(1<<inumber));
- return LIBUSB_SUCCESS;
-}
-
-int
-USBDeviceHandle::SetConfiguration(int config)
-{
- int config_index=fUSBDevice->CheckInterfacesFree(config);
- if(config_index==LIBUSB_ERROR_BUSY || config_index==LIBUSB_ERROR_NOT_FOUND)
- return config_index;
-
- usb_raw_command command;
- command.config.config_index=config_index;
- if(ioctl(fRawFD,B_USB_RAW_COMMAND_SET_CONFIGURATION,&command,
- sizeof(command)) || command.config.status != B_USB_RAW_STATUS_SUCCESS) {
- return _errno_to_libusb(command.config.status);
- }
- fUSBDevice->SetActiveConfiguration(config_index);
- return LIBUSB_SUCCESS;
-}
-
-int
-USBDeviceHandle::SetAltSetting(int inumber, int alt)
-{
- usb_raw_command command;
- command.alternate.config_index=fUSBDevice->ActiveConfigurationIndex();
- command.alternate.interface_index=inumber;
- if(ioctl(fRawFD,B_USB_RAW_COMMAND_GET_ACTIVE_ALT_INTERFACE_INDEX,&command,
- sizeof(command)) || command.alternate.status!=B_USB_RAW_STATUS_SUCCESS) {
- usbi_err(NULL,"Error retrieving active alternate interface");
- return _errno_to_libusb(command.alternate.status);
- }
- if(command.alternate.alternate_info == alt)
- {
- usbi_dbg("Setting alternate interface successful");
- return LIBUSB_SUCCESS;
- }
- command.alternate.alternate_info = alt;
- if(ioctl(fRawFD,B_USB_RAW_COMMAND_SET_ALT_INTERFACE,&command, //IF IOCTL FAILS DEVICE DISONNECTED PROBABLY
- sizeof(command)) || command.alternate.status!=B_USB_RAW_STATUS_SUCCESS) {
- usbi_err(NULL,"Error setting alternate interface");
- return _errno_to_libusb(command.alternate.status);
- }
- usbi_dbg("Setting alternate interface successful");
- return LIBUSB_SUCCESS;
-}
-
-
-USBDevice::USBDevice(const char * path)
- :
- fPath(NULL),
- fActiveConfiguration(0), //0?
- fConfigurationDescriptors(NULL),
- fClaimedInterfaces(0),
- fEndpointToIndex(NULL),
- fEndpointToInterface(NULL),
- fInitCheck(false)
-{
- fPath=strdup(path);
- Initialise();
-}
-
-USBDevice::~USBDevice()
-{
- free(fPath);
- if (fConfigurationDescriptors)
- {
- for(int i=0;i<fDeviceDescriptor.num_configurations;i++)
- {
- if (fConfigurationDescriptors[i])
- delete fConfigurationDescriptors[i];
- }
- delete[] fConfigurationDescriptors;
- }
- if (fEndpointToIndex)
- delete[] fEndpointToIndex;
- if (fEndpointToInterface)
- delete[] fEndpointToInterface;
-}
-
-bool
-USBDevice::InitCheck()
-{
- return fInitCheck;
-}
-
-const char*
-USBDevice::Location() const
-{
- return fPath;
-}
-
-uint8
-USBDevice::CountConfigurations() const
-{
- return fDeviceDescriptor.num_configurations;
-}
-
-const usb_device_descriptor*
-USBDevice::Descriptor() const
-{
- return &fDeviceDescriptor;
-}
-
-const usb_configuration_descriptor*
-USBDevice::ConfigurationDescriptor(uint32 index) const
-{
- if(index>CountConfigurations())
- return NULL;
- return (usb_configuration_descriptor*) fConfigurationDescriptors[index];
-}
-
-const usb_configuration_descriptor*
-USBDevice::ActiveConfiguration() const
-{
- return (usb_configuration_descriptor*) fConfigurationDescriptors[fActiveConfiguration];
-}
-
-int
-USBDevice::ActiveConfigurationIndex() const
-{
- return fActiveConfiguration;
-}
-
-int USBDevice::ClaimInterface(int interface)
-{
- if(interface>ActiveConfiguration()->number_interfaces)
- {
- return LIBUSB_ERROR_NOT_FOUND;
- }
- if((fClaimedInterfaces & (1<<interface)) !=0 )
- return LIBUSB_ERROR_BUSY;
- fClaimedInterfaces|=(1<<interface);
- return LIBUSB_SUCCESS;
-}
-
-int USBDevice::ReleaseInterface(int interface)
-{
- fClaimedInterfaces&=(!(1<<interface));
- return LIBUSB_SUCCESS;
-}
-
-int
-USBDevice::CheckInterfacesFree(int config)
-{
- if(fConfigToIndex.count(config)==0)
- return LIBUSB_ERROR_NOT_FOUND;
- if(fClaimedInterfaces==0)
- return fConfigToIndex[(uint8)config];
- return LIBUSB_ERROR_BUSY;
-}
-
-int
-USBDevice::SetActiveConfiguration(int config_index)
-{
- fActiveConfiguration=config_index;
- return LIBUSB_SUCCESS;
-}
-
-uint8
-USBDevice::EndpointToIndex(uint8 address) const
-{
- return fEndpointToIndex[fActiveConfiguration][address];
-}
-
-uint8
-USBDevice::EndpointToInterface(uint8 address) const
-{
- return fEndpointToInterface[fActiveConfiguration][address];
-}
-
-int
-USBDevice::Initialise() //Do we need more error checking, etc? How to report?
-{
- int fRawFD=open(fPath, O_RDWR | O_CLOEXEC);
- if(fRawFD < 0)
- return B_ERROR;
-
- usb_raw_command command;
- command.device.descriptor = &fDeviceDescriptor;
- if(ioctl(fRawFD, B_USB_RAW_COMMAND_GET_DEVICE_DESCRIPTOR, &command,
- sizeof(command)) || command.device.status != B_USB_RAW_STATUS_SUCCESS) {
- close(fRawFD);
- return B_ERROR;
- }
-
- size_t size;
- fConfigurationDescriptors = new(std::nothrow) unsigned char*[fDeviceDescriptor.num_configurations];
- fEndpointToIndex = new(std::nothrow) map<uint8,uint8> [fDeviceDescriptor.num_configurations];
- fEndpointToInterface = new(std::nothrow) map<uint8,uint8> [fDeviceDescriptor.num_configurations];
- for( int i=0; i<fDeviceDescriptor.num_configurations; i++)
- {
- size=0;
- usb_configuration_descriptor tmp_config;
- command.config.descriptor = &tmp_config;
- command.config.config_index = i;
- if(ioctl(fRawFD, B_USB_RAW_COMMAND_GET_CONFIGURATION_DESCRIPTOR, &command,
- sizeof(command)) || command.config.status != B_USB_RAW_STATUS_SUCCESS) {
- usbi_err(NULL,"failed retrieving configuration descriptor");
- close(fRawFD);
- return B_ERROR;
- }
- fConfigToIndex[tmp_config.configuration_value]=i;
- fConfigurationDescriptors[i]=new(std::nothrow) unsigned char[tmp_config.total_length];
- command.control.request_type=128;
- command.control.request=6;
- command.control.value=(2<<8)|i;
- command.control.index=0;
- command.control.length=tmp_config.total_length;
- command.control.data=fConfigurationDescriptors[i];
- if(ioctl(fRawFD,B_USB_RAW_COMMAND_CONTROL_TRANSFER,&command,
- sizeof(command)) || command.control.status!=B_USB_RAW_STATUS_SUCCESS) {
- usbi_err(NULL,"failed retrieving full configuration descriptor");
- close(fRawFD);
- return B_ERROR;
- }
- for( int j=0;j<tmp_config.number_interfaces;j++)
- {
- command.alternate.config_index=i;
- command.alternate.interface_index=j;
- if(ioctl(fRawFD,B_USB_RAW_COMMAND_GET_ALT_INTERFACE_COUNT, &command,
- sizeof(command)) || command.config.status != B_USB_RAW_STATUS_SUCCESS) {
- usbi_err(NULL,"failed retrieving number of alternate interfaces");
- close(fRawFD);
- return B_ERROR;
- }
- int num_alternate=command.alternate.alternate_info;
- for( int k=0;k<num_alternate;k++)
- {
- usb_interface_descriptor tmp_interface;
- command.interface_etc.config_index=i;
- command.interface_etc.interface_index=j;
- command.interface_etc.alternate_index=k;
- command.interface_etc.descriptor=&tmp_interface;
- if(ioctl(fRawFD,B_USB_RAW_COMMAND_GET_INTERFACE_DESCRIPTOR_ETC, &command,
- sizeof(command)) || command.config.status != B_USB_RAW_STATUS_SUCCESS) {
- usbi_err(NULL,"failed retrieving interface descriptor");
- close(fRawFD);
- return B_ERROR;
- }
- for( int l=0;l<tmp_interface.num_endpoints;l++)
- {
- usb_endpoint_descriptor tmp_endpoint;
- command.endpoint_etc.config_index=i;
- command.endpoint_etc.interface_index=j;
- command.endpoint_etc.alternate_index=k;
- command.endpoint_etc.endpoint_index=l;
- command.endpoint_etc.descriptor=&tmp_endpoint;
- if(ioctl(fRawFD,B_USB_RAW_COMMAND_GET_ENDPOINT_DESCRIPTOR_ETC, &command,
- sizeof(command)) || command.config.status != B_USB_RAW_STATUS_SUCCESS) {
- usbi_err(NULL,"failed retrieving endpoint descriptor");
- close(fRawFD);
- return B_ERROR;
- }
- fEndpointToIndex[i][tmp_endpoint.endpoint_address]=l;
- fEndpointToInterface[i][tmp_endpoint.endpoint_address]=j;
- }
- }
- }
- }
- close(fRawFD);
- fInitCheck = true;
- return B_OK;
-}
class WatchedEntry {
public:
- WatchedEntry(BMessenger*, entry_ref*);
+ WatchedEntry(BMessenger *, entry_ref *);
~WatchedEntry();
- bool EntryCreated(entry_ref* ref);
+ bool EntryCreated(entry_ref *ref);
bool EntryRemoved(ino_t node);
bool InitCheck();
class RosterLooper : public BLooper {
public:
- RosterLooper(USBRoster*);
+ RosterLooper(USBRoster *);
void Stop();
- virtual void MessageReceived(BMessage*);
+ virtual void MessageReceived(BMessage *);
bool InitCheck();
private:
};
-WatchedEntry::WatchedEntry(BMessenger* messenger, entry_ref* ref)
+WatchedEntry::WatchedEntry(BMessenger *messenger, entry_ref *ref)
: fMessenger(messenger),
fIsDirectory(false),
fDevice(NULL),
BDirectory directory;
if (entry.IsDirectory() && directory.SetTo(ref) >= B_OK) {
-
fIsDirectory = true;
while (directory.GetNextEntry(&entry) >= B_OK) {
if (entry.GetRef(ref) < B_OK)
continue;
- WatchedEntry* child = new(std::nothrow) WatchedEntry(fMessenger, ref);
+ WatchedEntry *child = new(std::nothrow) WatchedEntry(fMessenger, ref);
if (child == NULL)
continue;
- if (child->InitCheck() == false)
- {
+ if (child->InitCheck() == false) {
delete child;
continue;
}
-
child->fLink = fEntries;
fEntries = child;
}
watch_node(&fNode, B_WATCH_DIRECTORY, *fMessenger);
-
- } else {
+ }
+ else {
if (strncmp(ref->name, "raw", 3) == 0)
return;
unsigned long session_id = (unsigned long)&fDevice;
usbi_mutex_lock(&active_contexts_lock);
- list_for_each_entry(ctx, &active_contexts_list, list, struct libusb_context) {
-
- struct libusb_device* dev = usbi_get_device_by_session_id(ctx, session_id);
+ list_for_each_entry(ctx, &active_contexts_list, list, struct libusb_context) {
+ struct libusb_device *dev = usbi_get_device_by_session_id(ctx, session_id);
if (dev) {
usbi_dbg("using previously allocated device with location %lu", session_id);
libusb_unref_device(dev);
continue;
}
- usbi_dbg("allocating new device with location %lu" ,session_id);
+ usbi_dbg("allocating new device with location %lu", session_id);
dev = usbi_alloc_device(ctx, session_id);
if (!dev) {
usbi_dbg("device allocation failed");
continue;
}
- *((USBDevice**)dev->os_priv) = fDevice;
+ *((USBDevice **)dev->os_priv) = fDevice;
// Calculate pseudo-device-address
- int addr,tmp;
+ int addr, tmp;
if (strcmp(path.Leaf(), "hub") == 0)
- {
- tmp=100; //Random Number
- }
+ tmp = 100; //Random Number
else
- {
sscanf(path.Leaf(), "%d", &tmp);
- }
addr = tmp + 1;
path.GetParent(&parent_path);
- while(strcmp(parent_path.Leaf(),"usb") != 0)
- {
+ while (strcmp(parent_path.Leaf(), "usb") != 0) {
sscanf(parent_path.Leaf(), "%d", &tmp);
addr += tmp + 1;
parent_path.GetParent(&parent_path);
}
sscanf(path.Path(), "/dev/bus/usb/%d", &dev->bus_number);
- (dev->device_address) = addr - (dev->bus_number + 1);
+ dev->device_address = addr - (dev->bus_number + 1);
- if(usbi_sanitize_device(dev) < 0)
- {
+ if (usbi_sanitize_device(dev) < 0) {
usbi_dbg("device sanitization failed");
libusb_unref_device(dev);
continue;
usbi_connect_device(dev);
}
usbi_mutex_unlock(&active_contexts_lock);
- } else if (fDevice) {
+ }
+ else if (fDevice) {
delete fDevice;
fDevice = NULL;
return;
if (fIsDirectory) {
watch_node(&fNode, B_STOP_WATCHING, *fMessenger);
- WatchedEntry* child = fEntries;
+ WatchedEntry *child = fEntries;
while (child) {
WatchedEntry *next = child->fLink;
delete child;
}
if (fDevice) {
- // Remove this device from each active context's device list
+ // Remove this device from each active context's device list
struct libusb_context *ctx;
struct libusb_device *dev;
unsigned long session_id = (unsigned long)&fDevice;
usbi_mutex_lock(&active_contexts_lock);
list_for_each_entry(ctx, &active_contexts_list, list, struct libusb_context) {
- dev = usbi_get_device_by_session_id (ctx, session_id);
+ dev = usbi_get_device_by_session_id(ctx, session_id);
if (dev != NULL) {
- usbi_disconnect_device (dev);
+ usbi_disconnect_device(dev);
libusb_unref_device(dev);
} else {
usbi_dbg("device with location %lu not found", session_id);
bool
WatchedEntry::EntryCreated(entry_ref *ref)
{
- if (!fIsDirectory)
+ if (!fIsDirectory)
return false;
if (ref->directory != fNode.node) {
- WatchedEntry* child = fEntries;
+ WatchedEntry *child = fEntries;
while (child) {
if (child->EntryCreated(ref))
return true;
return false;
}
- WatchedEntry* child = new(std::nothrow) WatchedEntry(fMessenger, ref);
+ WatchedEntry *child = new(std::nothrow) WatchedEntry(fMessenger, ref);
if (child == NULL)
return false;
child->fLink = fEntries;
if (!fIsDirectory)
return false;
- WatchedEntry* child = fEntries;
- WatchedEntry* lastChild = NULL;
+ WatchedEntry *child = fEntries;
+ WatchedEntry *lastChild = NULL;
while (child) {
if (child->fNode.node == node) {
if (lastChild)
}
-RosterLooper::RosterLooper(USBRoster* roster)
+RosterLooper::RosterLooper(USBRoster *roster)
: BLooper("LibusbRoster Looper"),
fRoster(roster),
fRoot(NULL),
{
BEntry entry("/dev/bus/usb");
if (!entry.Exists()) {
- usbi_err(NULL,"usb_raw not published");
+ usbi_err(NULL, "usb_raw not published");
return;
}
Run();
fMessenger = new(std::nothrow) BMessenger(this);
- if (fMessenger == NULL)
- {
- usbi_err(NULL,"error creating BMessenger object");
+ if (fMessenger == NULL) {
+ usbi_err(NULL, "error creating BMessenger object");
return;
}
- if(Lock()) {
+ if (Lock()) {
entry_ref ref;
entry.GetRef(&ref);
fRoot = new(std::nothrow) WatchedEntry(fMessenger, &ref);
Unlock();
if (fRoot == NULL)
- {
return;
- }
- if (fRoot->InitCheck() == false)
- {
+ if (fRoot->InitCheck() == false) {
delete fRoot;
+ fRoot = NULL;
return;
}
}
return;
switch (opcode) {
- case B_ENTRY_CREATED: {
+ case B_ENTRY_CREATED:
+ {
dev_t device;
ino_t directory;
- const char* name;
- if (message->FindInt32("device", &device) < B_OK
- || message->FindInt64("directory", &directory) < B_OK
- || message->FindString("name", &name) < B_OK)
+ const char *name;
+ if (message->FindInt32("device", &device) < B_OK ||
+ message->FindInt64("directory", &directory) < B_OK ||
+ message->FindString("name", &name) < B_OK)
break;
entry_ref ref(device, directory, name);
fRoot->EntryCreated(&ref);
break;
}
- case B_ENTRY_REMOVED: {
+ case B_ENTRY_REMOVED:
+ {
ino_t node;
if (message->FindInt64("node", &node) < B_OK)
break;
int
USBRoster::Start()
{
- if(fLooper)
- return LIBUSB_SUCCESS;
-
- fLooper = new(std::nothrow) RosterLooper(this);
- if (fLooper == NULL || ((RosterLooper*)fLooper)->InitCheck() == false)
- return LIBUSB_ERROR_OTHER;
+ if (fLooper == NULL) {
+ fLooper = new(std::nothrow) RosterLooper(this);
+ if (fLooper == NULL || ((RosterLooper *)fLooper)->InitCheck() == false) {
+ if (fLooper)
+ fLooper = NULL;
+ return LIBUSB_ERROR_OTHER;
+ }
+ }
return LIBUSB_SUCCESS;
}
void
USBRoster::Stop()
{
- if(!fLooper)
- return;
-
- ((RosterLooper *)fLooper)->Stop();
- fLooper = NULL;
+ if (fLooper) {
+ ((RosterLooper *)fLooper)->Stop();
+ fLooper = NULL;
+ }
}
-
-
class USBDevice {
public:
USBDevice(const char *);
- virtual ~USBDevice();
- const char* Location() const;
- uint8 CountConfigurations() const;
- const usb_device_descriptor* Descriptor() const;
- const usb_configuration_descriptor* ConfigurationDescriptor(uint32) const;
- const usb_configuration_descriptor* ActiveConfiguration() const;
- uint8 EndpointToIndex(uint8) const;
- uint8 EndpointToInterface(uint8) const;
- int ClaimInterface(int);
- int ReleaseInterface(int);
- int CheckInterfacesFree(int);
- int SetActiveConfiguration(int);
+ virtual ~USBDevice();
+ const char* Location() const;
+ uint8 CountConfigurations() const;
+ const usb_device_descriptor* Descriptor() const;
+ const usb_configuration_descriptor* ConfigurationDescriptor(uint32) const;
+ const usb_configuration_descriptor* ActiveConfiguration() const;
+ uint8 EndpointToIndex(uint8) const;
+ uint8 EndpointToInterface(uint8) const;
+ int ClaimInterface(int);
+ int ReleaseInterface(int);
+ int CheckInterfacesFree(int);
+ int SetActiveConfiguration(int);
int ActiveConfigurationIndex() const;
bool InitCheck();
private:
class USBDeviceHandle {
public:
- USBDeviceHandle(USBDevice* dev);
+ USBDeviceHandle(USBDevice *dev);
virtual ~USBDeviceHandle();
- int ClaimInterface(int);
- int ReleaseInterface(int);
- int SetConfiguration(int);
- int SetAltSetting(int,int);
- status_t SubmitTransfer(struct usbi_transfer*);
- status_t CancelTransfer(USBTransfer*);
+ int ClaimInterface(int);
+ int ReleaseInterface(int);
+ int SetConfiguration(int);
+ int SetAltSetting(int, int);
+ status_t SubmitTransfer(struct usbi_transfer *);
+ status_t CancelTransfer(USBTransfer *);
bool InitCheck();
private:
- int fRawFD;
+ int fRawFD;
static status_t TransfersThread(void *);
- void TransfersWorker();
+ void TransfersWorker();
USBDevice* fUSBDevice;
unsigned int fClaimedInterfaces;
- BList fTransfers;
- BLocker fTransfersLock;
- sem_id fTransfersSem;
- thread_id fTransfersThread;
+ BList fTransfers;
+ BLocker fTransfersLock;
+ sem_id fTransfersSem;
+ thread_id fTransfersThread;
bool fInitCheck;
};
class USBTransfer {
public:
- USBTransfer(struct usbi_transfer*,USBDevice*);
+ USBTransfer(struct usbi_transfer *, USBDevice *);
virtual ~USBTransfer();
void Do(int);
struct usbi_transfer* UsbiTransfer();
--- /dev/null
+/*
+ * Haiku Backend for libusb
+ * Copyright © 2014 Akshay Jaggi <akshay1994.leo@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <new>
+#include <vector>
+
+#include "haiku_usb.h"
+
+int _errno_to_libusb(int status)
+{
+ return status;
+}
+
+USBTransfer::USBTransfer(struct usbi_transfer *itransfer, USBDevice *device)
+{
+ fUsbiTransfer = itransfer;
+ fLibusbTransfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
+ fUSBDevice = device;
+ fCancelled = false;
+}
+
+USBTransfer::~USBTransfer()
+{
+}
+
+struct usbi_transfer *
+USBTransfer::UsbiTransfer()
+{
+ return fUsbiTransfer;
+}
+
+void
+USBTransfer::SetCancelled()
+{
+ fCancelled = true;
+}
+
+bool
+USBTransfer::IsCancelled()
+{
+ return fCancelled;
+}
+
+void
+USBTransfer::Do(int fRawFD)
+{
+ switch (fLibusbTransfer->type) {
+ case LIBUSB_TRANSFER_TYPE_CONTROL:
+ {
+ struct libusb_control_setup *setup = (struct libusb_control_setup *)fLibusbTransfer->buffer;
+ usb_raw_command command;
+ command.control.request_type = setup->bmRequestType;
+ command.control.request = setup->bRequest;
+ command.control.value = setup->wValue;
+ command.control.index = setup->wIndex;
+ command.control.length = setup->wLength;
+ command.control.data = fLibusbTransfer->buffer + LIBUSB_CONTROL_SETUP_SIZE;
+ if (fCancelled)
+ break;
+ if (ioctl(fRawFD, B_USB_RAW_COMMAND_CONTROL_TRANSFER, &command, sizeof(command)) ||
+ command.control.status != B_USB_RAW_STATUS_SUCCESS) {
+ fUsbiTransfer->transferred = -1;
+ usbi_err(TRANSFER_CTX(fLibusbTransfer), "failed control transfer");
+ break;
+ }
+ fUsbiTransfer->transferred = command.control.length;
+ }
+ break;
+ case LIBUSB_TRANSFER_TYPE_BULK:
+ case LIBUSB_TRANSFER_TYPE_INTERRUPT:
+ {
+ usb_raw_command command;
+ command.transfer.interface = fUSBDevice->EndpointToInterface(fLibusbTransfer->endpoint);
+ command.transfer.endpoint = fUSBDevice->EndpointToIndex(fLibusbTransfer->endpoint);
+ command.transfer.data = fLibusbTransfer->buffer;
+ command.transfer.length = fLibusbTransfer->length;
+ if (fCancelled)
+ break;
+ if (fLibusbTransfer->type == LIBUSB_TRANSFER_TYPE_BULK) {
+ if (ioctl(fRawFD, B_USB_RAW_COMMAND_BULK_TRANSFER, &command, sizeof(command)) ||
+ command.transfer.status != B_USB_RAW_STATUS_SUCCESS) {
+ fUsbiTransfer->transferred = -1;
+ usbi_err(TRANSFER_CTX(fLibusbTransfer), "failed bulk transfer");
+ break;
+ }
+ }
+ else {
+ if (ioctl(fRawFD, B_USB_RAW_COMMAND_INTERRUPT_TRANSFER, &command, sizeof(command)) ||
+ command.transfer.status != B_USB_RAW_STATUS_SUCCESS) {
+ fUsbiTransfer->transferred = -1;
+ usbi_err(TRANSFER_CTX(fLibusbTransfer), "failed interrupt transfer");
+ break;
+ }
+ }
+ fUsbiTransfer->transferred = command.transfer.length;
+ }
+ break;
+ // IsochronousTransfers not tested
+ case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
+ {
+ usb_raw_command command;
+ command.isochronous.interface = fUSBDevice->EndpointToInterface(fLibusbTransfer->endpoint);
+ command.isochronous.endpoint = fUSBDevice->EndpointToIndex(fLibusbTransfer->endpoint);
+ command.isochronous.data = fLibusbTransfer->buffer;
+ command.isochronous.length = fLibusbTransfer->length;
+ command.isochronous.packet_count = fLibusbTransfer->num_iso_packets;
+ int i;
+ usb_iso_packet_descriptor *packetDescriptors = new usb_iso_packet_descriptor[fLibusbTransfer->num_iso_packets];
+ for (i = 0; i < fLibusbTransfer->num_iso_packets; i++) {
+ if ((int16)(fLibusbTransfer->iso_packet_desc[i]).length != (fLibusbTransfer->iso_packet_desc[i]).length) {
+ fUsbiTransfer->transferred = -1;
+ usbi_err(TRANSFER_CTX(fLibusbTransfer), "failed isochronous transfer");
+ break;
+ }
+ packetDescriptors[i].request_length = (int16)(fLibusbTransfer->iso_packet_desc[i]).length;
+ }
+ if (i < fLibusbTransfer->num_iso_packets)
+ break; // TODO Handle this error
+ command.isochronous.packet_descriptors = packetDescriptors;
+ if (fCancelled)
+ break;
+ if (ioctl(fRawFD, B_USB_RAW_COMMAND_ISOCHRONOUS_TRANSFER, &command, sizeof(command)) ||
+ command.isochronous.status != B_USB_RAW_STATUS_SUCCESS) {
+ fUsbiTransfer->transferred = -1;
+ usbi_err(TRANSFER_CTX(fLibusbTransfer), "failed isochronous transfer");
+ break;
+ }
+ for (i = 0; i < fLibusbTransfer->num_iso_packets; i++) {
+ (fLibusbTransfer->iso_packet_desc[i]).actual_length = packetDescriptors[i].actual_length;
+ switch (packetDescriptors[i].status) {
+ case B_OK:
+ (fLibusbTransfer->iso_packet_desc[i]).status = LIBUSB_TRANSFER_COMPLETED;
+ break;
+ default:
+ (fLibusbTransfer->iso_packet_desc[i]).status = LIBUSB_TRANSFER_ERROR;
+ break;
+ }
+ }
+ delete[] packetDescriptors;
+ // Do we put the length of transfer here, for isochronous transfers?
+ fUsbiTransfer->transferred = command.transfer.length;
+ }
+ break;
+ default:
+ usbi_err(TRANSFER_CTX(fLibusbTransfer), "Unknown type of transfer");
+ }
+}
+
+bool
+USBDeviceHandle::InitCheck()
+{
+ return fInitCheck;
+}
+
+status_t
+USBDeviceHandle::TransfersThread(void *self)
+{
+ USBDeviceHandle *handle = (USBDeviceHandle *)self;
+ handle->TransfersWorker();
+ return B_OK;
+}
+
+void
+USBDeviceHandle::TransfersWorker()
+{
+ while (true) {
+ status_t status = acquire_sem(fTransfersSem);
+ if (status == B_BAD_SEM_ID)
+ break;
+ if (status == B_INTERRUPTED)
+ continue;
+ fTransfersLock.Lock();
+ USBTransfer *fPendingTransfer = (USBTransfer *) fTransfers.RemoveItem((int32)0);
+ fTransfersLock.Unlock();
+ fPendingTransfer->Do(fRawFD);
+ usbi_signal_transfer_completion(fPendingTransfer->UsbiTransfer());
+ }
+}
+
+status_t
+USBDeviceHandle::SubmitTransfer(struct usbi_transfer *itransfer)
+{
+ USBTransfer *transfer = new USBTransfer(itransfer, fUSBDevice);
+ *((USBTransfer **)usbi_transfer_get_os_priv(itransfer)) = transfer;
+ BAutolock locker(fTransfersLock);
+ fTransfers.AddItem(transfer);
+ release_sem(fTransfersSem);
+ return LIBUSB_SUCCESS;
+}
+
+status_t
+USBDeviceHandle::CancelTransfer(USBTransfer *transfer)
+{
+ transfer->SetCancelled();
+ fTransfersLock.Lock();
+ bool removed = fTransfers.RemoveItem(transfer);
+ fTransfersLock.Unlock();
+ if(removed)
+ usbi_signal_transfer_completion(transfer->UsbiTransfer());
+ return LIBUSB_SUCCESS;
+}
+
+USBDeviceHandle::USBDeviceHandle(USBDevice *dev)
+ :
+ fTransfersThread(-1),
+ fUSBDevice(dev),
+ fClaimedInterfaces(0),
+ fInitCheck(false)
+{
+ fRawFD = open(dev->Location(), O_RDWR | O_CLOEXEC);
+ if (fRawFD < 0) {
+ usbi_err(NULL,"failed to open device");
+ return;
+ }
+ fTransfersSem = create_sem(0, "Transfers Queue Sem");
+ fTransfersThread = spawn_thread(TransfersThread, "Transfer Worker", B_NORMAL_PRIORITY, this);
+ resume_thread(fTransfersThread);
+ fInitCheck = true;
+}
+
+USBDeviceHandle::~USBDeviceHandle()
+{
+ if (fRawFD > 0)
+ close(fRawFD);
+ for(int i = 0; i < 32; i++) {
+ if (fClaimedInterfaces & (1 << i))
+ ReleaseInterface(i);
+ }
+ delete_sem(fTransfersSem);
+ if (fTransfersThread > 0)
+ wait_for_thread(fTransfersThread, NULL);
+}
+
+int
+USBDeviceHandle::ClaimInterface(int inumber)
+{
+ int status = fUSBDevice->ClaimInterface(inumber);
+ if (status == LIBUSB_SUCCESS)
+ fClaimedInterfaces |= (1 << inumber);
+ return status;
+}
+
+int
+USBDeviceHandle::ReleaseInterface(int inumber)
+{
+ fUSBDevice->ReleaseInterface(inumber);
+ fClaimedInterfaces &= ~(1 << inumber);
+ return LIBUSB_SUCCESS;
+}
+
+int
+USBDeviceHandle::SetConfiguration(int config)
+{
+ int config_index = fUSBDevice->CheckInterfacesFree(config);
+ if(config_index == LIBUSB_ERROR_BUSY || config_index == LIBUSB_ERROR_NOT_FOUND)
+ return config_index;
+ usb_raw_command command;
+ command.config.config_index = config_index;
+ if (ioctl(fRawFD, B_USB_RAW_COMMAND_SET_CONFIGURATION, &command, sizeof(command)) ||
+ command.config.status != B_USB_RAW_STATUS_SUCCESS) {
+ return _errno_to_libusb(command.config.status);
+ }
+ fUSBDevice->SetActiveConfiguration(config_index);
+ return LIBUSB_SUCCESS;
+}
+
+int
+USBDeviceHandle::SetAltSetting(int inumber, int alt)
+{
+ usb_raw_command command;
+ command.alternate.config_index = fUSBDevice->ActiveConfigurationIndex();
+ command.alternate.interface_index = inumber;
+ if (ioctl(fRawFD, B_USB_RAW_COMMAND_GET_ACTIVE_ALT_INTERFACE_INDEX, &command, sizeof(command)) ||
+ command.alternate.status != B_USB_RAW_STATUS_SUCCESS) {
+ usbi_err(NULL, "Error retrieving active alternate interface");
+ return _errno_to_libusb(command.alternate.status);
+ }
+ if (command.alternate.alternate_info == alt) {
+ usbi_dbg("Setting alternate interface successful");
+ return LIBUSB_SUCCESS;
+ }
+ command.alternate.alternate_info = alt;
+ if (ioctl(fRawFD, B_USB_RAW_COMMAND_SET_ALT_INTERFACE, &command, sizeof(command)) ||
+ command.alternate.status != B_USB_RAW_STATUS_SUCCESS) { //IF IOCTL FAILS DEVICE DISONNECTED PROBABLY
+ usbi_err(NULL, "Error setting alternate interface");
+ return _errno_to_libusb(command.alternate.status);
+ }
+ usbi_dbg("Setting alternate interface successful");
+ return LIBUSB_SUCCESS;
+}
+
+
+USBDevice::USBDevice(const char *path)
+ :
+ fPath(NULL),
+ fActiveConfiguration(0), //0?
+ fConfigurationDescriptors(NULL),
+ fClaimedInterfaces(0),
+ fEndpointToIndex(NULL),
+ fEndpointToInterface(NULL),
+ fInitCheck(false)
+{
+ fPath=strdup(path);
+ Initialise();
+}
+
+USBDevice::~USBDevice()
+{
+ free(fPath);
+ if (fConfigurationDescriptors) {
+ for(int i = 0; i < fDeviceDescriptor.num_configurations; i++) {
+ if (fConfigurationDescriptors[i])
+ delete fConfigurationDescriptors[i];
+ }
+ delete[] fConfigurationDescriptors;
+ }
+ if (fEndpointToIndex)
+ delete[] fEndpointToIndex;
+ if (fEndpointToInterface)
+ delete[] fEndpointToInterface;
+}
+
+bool
+USBDevice::InitCheck()
+{
+ return fInitCheck;
+}
+
+const char *
+USBDevice::Location() const
+{
+ return fPath;
+}
+
+uint8
+USBDevice::CountConfigurations() const
+{
+ return fDeviceDescriptor.num_configurations;
+}
+
+const usb_device_descriptor *
+USBDevice::Descriptor() const
+{
+ return &fDeviceDescriptor;
+}
+
+const usb_configuration_descriptor *
+USBDevice::ConfigurationDescriptor(uint32 index) const
+{
+ if (index > CountConfigurations())
+ return NULL;
+ return (usb_configuration_descriptor *) fConfigurationDescriptors[index];
+}
+
+const usb_configuration_descriptor *
+USBDevice::ActiveConfiguration() const
+{
+ return (usb_configuration_descriptor *) fConfigurationDescriptors[fActiveConfiguration];
+}
+
+int
+USBDevice::ActiveConfigurationIndex() const
+{
+ return fActiveConfiguration;
+}
+
+int USBDevice::ClaimInterface(int interface)
+{
+ if (interface > ActiveConfiguration()->number_interfaces)
+ return LIBUSB_ERROR_NOT_FOUND;
+ if (fClaimedInterfaces & (1 << interface))
+ return LIBUSB_ERROR_BUSY;
+ fClaimedInterfaces |= (1 << interface);
+ return LIBUSB_SUCCESS;
+}
+
+int USBDevice::ReleaseInterface(int interface)
+{
+ fClaimedInterfaces &= ~(1 << interface);
+ return LIBUSB_SUCCESS;
+}
+
+int
+USBDevice::CheckInterfacesFree(int config)
+{
+ if (fConfigToIndex.count(config) == 0)
+ return LIBUSB_ERROR_NOT_FOUND;
+ if (fClaimedInterfaces == 0)
+ return fConfigToIndex[(uint8)config];
+ return LIBUSB_ERROR_BUSY;
+}
+
+int
+USBDevice::SetActiveConfiguration(int config_index)
+{
+ fActiveConfiguration = config_index;
+ return LIBUSB_SUCCESS;
+}
+
+uint8
+USBDevice::EndpointToIndex(uint8 address) const
+{
+ return fEndpointToIndex[fActiveConfiguration][address];
+}
+
+uint8
+USBDevice::EndpointToInterface(uint8 address) const
+{
+ return fEndpointToInterface[fActiveConfiguration][address];
+}
+
+int
+USBDevice::Initialise() //Do we need more error checking, etc? How to report?
+{
+ int fRawFD = open(fPath, O_RDWR | O_CLOEXEC);
+ if (fRawFD < 0)
+ return B_ERROR;
+ usb_raw_command command;
+ command.device.descriptor = &fDeviceDescriptor;
+ if (ioctl(fRawFD, B_USB_RAW_COMMAND_GET_DEVICE_DESCRIPTOR, &command, sizeof(command)) ||
+ command.device.status != B_USB_RAW_STATUS_SUCCESS) {
+ close(fRawFD);
+ return B_ERROR;
+ }
+
+ fConfigurationDescriptors = new(std::nothrow) unsigned char *[fDeviceDescriptor.num_configurations];
+ fEndpointToIndex = new(std::nothrow) map<uint8,uint8> [fDeviceDescriptor.num_configurations];
+ fEndpointToInterface = new(std::nothrow) map<uint8,uint8> [fDeviceDescriptor.num_configurations];
+ for (int i = 0; i < fDeviceDescriptor.num_configurations; i++) {
+ usb_configuration_descriptor tmp_config;
+ command.config.descriptor = &tmp_config;
+ command.config.config_index = i;
+ if (ioctl(fRawFD, B_USB_RAW_COMMAND_GET_CONFIGURATION_DESCRIPTOR, &command, sizeof(command)) ||
+ command.config.status != B_USB_RAW_STATUS_SUCCESS) {
+ usbi_err(NULL, "failed retrieving configuration descriptor");
+ close(fRawFD);
+ return B_ERROR;
+ }
+ fConfigToIndex[tmp_config.configuration_value] = i;
+ fConfigurationDescriptors[i] = new(std::nothrow) unsigned char[tmp_config.total_length];
+ command.control.request_type = 128;
+ command.control.request = 6;
+ command.control.value = (2 << 8) | i;
+ command.control.index = 0;
+ command.control.length = tmp_config.total_length;
+ command.control.data = fConfigurationDescriptors[i];
+ if (ioctl(fRawFD, B_USB_RAW_COMMAND_CONTROL_TRANSFER, &command, sizeof(command)) ||
+ command.control.status!=B_USB_RAW_STATUS_SUCCESS) {
+ usbi_err(NULL, "failed retrieving full configuration descriptor");
+ close(fRawFD);
+ return B_ERROR;
+ }
+ for (int j = 0; j < tmp_config.number_interfaces; j++) {
+ command.alternate.config_index = i;
+ command.alternate.interface_index = j;
+ if (ioctl(fRawFD, B_USB_RAW_COMMAND_GET_ALT_INTERFACE_COUNT, &command, sizeof(command)) ||
+ command.config.status != B_USB_RAW_STATUS_SUCCESS) {
+ usbi_err(NULL, "failed retrieving number of alternate interfaces");
+ close(fRawFD);
+ return B_ERROR;
+ }
+ int num_alternate = command.alternate.alternate_info;
+ for (int k = 0; k < num_alternate; k++) {
+ usb_interface_descriptor tmp_interface;
+ command.interface_etc.config_index = i;
+ command.interface_etc.interface_index = j;
+ command.interface_etc.alternate_index = k;
+ command.interface_etc.descriptor = &tmp_interface;
+ if (ioctl(fRawFD, B_USB_RAW_COMMAND_GET_INTERFACE_DESCRIPTOR_ETC, &command, sizeof(command)) ||
+ command.config.status != B_USB_RAW_STATUS_SUCCESS) {
+ usbi_err(NULL, "failed retrieving interface descriptor");
+ close(fRawFD);
+ return B_ERROR;
+ }
+ for (int l = 0; l < tmp_interface.num_endpoints; l++) {
+ usb_endpoint_descriptor tmp_endpoint;
+ command.endpoint_etc.config_index = i;
+ command.endpoint_etc.interface_index = j;
+ command.endpoint_etc.alternate_index = k;
+ command.endpoint_etc.endpoint_index = l;
+ command.endpoint_etc.descriptor = &tmp_endpoint;
+ if (ioctl(fRawFD, B_USB_RAW_COMMAND_GET_ENDPOINT_DESCRIPTOR_ETC, &command, sizeof(command)) ||
+ command.config.status != B_USB_RAW_STATUS_SUCCESS) {
+ usbi_err(NULL, "failed retrieving endpoint descriptor");
+ close(fRawFD);
+ return B_ERROR;
+ }
+ fEndpointToIndex[i][tmp_endpoint.endpoint_address] = l;
+ fEndpointToInterface[i][tmp_endpoint.endpoint_address] = j;
+ }
+ }
+ }
+ }
+ close(fRawFD);
+ fInitCheck = true;
+ return B_OK;
+}
#include "haiku_usb.h"
-USBRoster gUsbRoster;
-int32 gInitCount = 0;
+USBRoster gUsbRoster;
+int32 gInitCount = 0;
static int
-haiku_init(struct libusb_context* ctx)
+haiku_init(struct libusb_context *ctx)
{
if (atomic_add(&gInitCount, 1) == 0)
- {
return gUsbRoster.Start();
- }
return LIBUSB_SUCCESS;
}
gUsbRoster.Stop();
}
-static int
+static int
haiku_open(struct libusb_device_handle *dev_handle)
{
- USBDevice* dev=*((USBDevice**)dev_handle->dev->os_priv);
- USBDeviceHandle *handle=new(std::nothrow) USBDeviceHandle(dev);
+ USBDevice *dev = *((USBDevice **)dev_handle->dev->os_priv);
+ USBDeviceHandle *handle = new(std::nothrow) USBDeviceHandle(dev);
if (handle == NULL)
return LIBUSB_ERROR_NO_MEM;
- if (handle->InitCheck() == false)
- {
+ if (handle->InitCheck() == false) {
delete handle;
return LIBUSB_ERROR_NO_DEVICE;
}
- *((USBDeviceHandle**)dev_handle->os_priv)=handle;
+ *((USBDeviceHandle **)dev_handle->os_priv) = handle;
return LIBUSB_SUCCESS;
}
-static void
+static void
haiku_close(struct libusb_device_handle *dev_handle)
{
- USBDeviceHandle * handle=*((USBDeviceHandle**)dev_handle->os_priv);
- if(handle==NULL)
+ USBDeviceHandle *handle = *((USBDeviceHandle **)dev_handle->os_priv);
+ if (handle == NULL)
return;
delete handle;
- *((USBDeviceHandle**)dev_handle->os_priv)=NULL;
+ *((USBDeviceHandle **)dev_handle->os_priv) = NULL;
}
-static int
-haiku_get_device_descriptor(struct libusb_device *device, unsigned char* buffer, int *host_endian)
+static int
+haiku_get_device_descriptor(struct libusb_device *device, unsigned char *buffer, int *host_endian)
{
- USBDevice *dev = *((USBDevice**)(device->os_priv));
- memcpy(buffer,dev->Descriptor(),DEVICE_DESC_LENGTH);
- *host_endian=0;
- return LIBUSB_SUCCESS;
+ USBDevice *dev = *((USBDevice **)device->os_priv);
+ memcpy(buffer, dev->Descriptor(), DEVICE_DESC_LENGTH);
+ *host_endian = 0;
+ return LIBUSB_SUCCESS;
}
static int
haiku_get_active_config_descriptor(struct libusb_device *device, unsigned char *buffer, size_t len, int *host_endian)
{
- USBDevice *dev = *((USBDevice**)(device->os_priv));
- const usb_configuration_descriptor* act_config = dev->ActiveConfiguration();
- if(len>act_config->total_length)
- {
+ USBDevice *dev = *((USBDevice **)device->os_priv);
+ const usb_configuration_descriptor *act_config = dev->ActiveConfiguration();
+ if (len > act_config->total_length)
return LIBUSB_ERROR_OVERFLOW;
- }
- memcpy(buffer,act_config,len);
- *host_endian=0;
+ memcpy(buffer, act_config, len);
+ *host_endian = 0;
return LIBUSB_SUCCESS;
}
static int
haiku_get_config_descriptor(struct libusb_device *device, uint8_t config_index, unsigned char *buffer, size_t len, int *host_endian)
{
- USBDevice *dev = *((USBDevice**)(device->os_priv));
- const usb_configuration_descriptor* config = dev->ConfigurationDescriptor(config_index);
- if(config==NULL)
- {
- usbi_err(DEVICE_CTX(device),"failed getting configuration descriptor");
+ USBDevice *dev = *((USBDevice **)device->os_priv);
+ const usb_configuration_descriptor *config = dev->ConfigurationDescriptor(config_index);
+ if (config == NULL) {
+ usbi_err(DEVICE_CTX(device), "failed getting configuration descriptor");
return LIBUSB_ERROR_INVALID_PARAM;
}
- if(len>config->total_length)
- len=config->total_length;
- memcpy(buffer,(unsigned char*)config,len);
- *host_endian=0;
+ if (len > config->total_length)
+ len = config->total_length;
+ memcpy(buffer, config, len);
+ *host_endian = 0;
return len;
}
static int
haiku_set_configuration(struct libusb_device_handle *dev_handle, int config)
{
- USBDeviceHandle * handle= *((USBDeviceHandle**)dev_handle->os_priv);
+ USBDeviceHandle *handle= *((USBDeviceHandle **)dev_handle->os_priv);
return handle->SetConfiguration(config);
}
static int
haiku_claim_interface(struct libusb_device_handle *dev_handle, int interface_number)
{
- USBDeviceHandle * handle=*((USBDeviceHandle**)dev_handle->os_priv);
+ USBDeviceHandle *handle = *((USBDeviceHandle **)dev_handle->os_priv);
return handle->ClaimInterface(interface_number);
}
static int
-haiku_set_altsetting(struct libusb_device_handle* dev_handle, int interface_number, int altsetting)
+haiku_set_altsetting(struct libusb_device_handle *dev_handle, int interface_number, int altsetting)
{
- USBDeviceHandle* handle = *((USBDeviceHandle**)dev_handle->os_priv);
+ USBDeviceHandle *handle = *((USBDeviceHandle **)dev_handle->os_priv);
return handle->SetAltSetting(interface_number, altsetting);
}
static int
haiku_release_interface(struct libusb_device_handle *dev_handle, int interface_number)
{
- USBDeviceHandle * handle=*((USBDeviceHandle**)dev_handle->os_priv);
- haiku_set_altsetting(dev_handle,interface_number,0);
+ USBDeviceHandle *handle = *((USBDeviceHandle **)dev_handle->os_priv);
+ haiku_set_altsetting(dev_handle,interface_number, 0);
return handle->ReleaseInterface(interface_number);
}
static int
-haiku_submit_transfer(struct usbi_transfer * itransfer)
+haiku_submit_transfer(struct usbi_transfer *itransfer)
{
- struct libusb_transfer* fLibusbTransfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
- USBDeviceHandle * fDeviceHandle = *((USBDeviceHandle**)fLibusbTransfer->dev_handle->os_priv);
+ struct libusb_transfer *fLibusbTransfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
+ USBDeviceHandle *fDeviceHandle = *((USBDeviceHandle **)fLibusbTransfer->dev_handle->os_priv);
return fDeviceHandle->SubmitTransfer(itransfer);
}
static int
-haiku_cancel_transfer(struct usbi_transfer * itransfer)
+haiku_cancel_transfer(struct usbi_transfer *itransfer)
{
- struct libusb_transfer* fLibusbTransfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
- USBDeviceHandle * fDeviceHandle = *((USBDeviceHandle**)fLibusbTransfer->dev_handle->os_priv);
- return fDeviceHandle->CancelTransfer(*((USBTransfer**)usbi_transfer_get_os_priv(itransfer)));
+ struct libusb_transfer *fLibusbTransfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
+ USBDeviceHandle *fDeviceHandle = *((USBDeviceHandle **)fLibusbTransfer->dev_handle->os_priv);
+ return fDeviceHandle->CancelTransfer(*((USBTransfer **)usbi_transfer_get_os_priv(itransfer)));
}
static void
-haiku_clear_transfer_priv(struct usbi_transfer * itransfer)
+haiku_clear_transfer_priv(struct usbi_transfer *itransfer)
{
- USBTransfer* transfer=*((USBTransfer**)usbi_transfer_get_os_priv(itransfer));
+ USBTransfer *transfer = *((USBTransfer **)usbi_transfer_get_os_priv(itransfer));
delete transfer;
- *((USBTransfer**)usbi_transfer_get_os_priv(itransfer))=NULL;
+ *((USBTransfer **)usbi_transfer_get_os_priv(itransfer)) = NULL;
}
static int
-haiku_handle_transfer_completion(struct usbi_transfer * itransfer)
+haiku_handle_transfer_completion(struct usbi_transfer *itransfer)
{
- USBTransfer* transfer=*((USBTransfer**)usbi_transfer_get_os_priv(itransfer));
+ USBTransfer *transfer = *((USBTransfer **)usbi_transfer_get_os_priv(itransfer));
usbi_mutex_lock(&itransfer->lock);
- if(transfer->IsCancelled())
- {
+ if (transfer->IsCancelled()) {
delete transfer;
- *((USBTransfer**)usbi_transfer_get_os_priv(itransfer))=NULL;
+ *((USBTransfer **)usbi_transfer_get_os_priv(itransfer)) = NULL;
usbi_mutex_unlock(&itransfer->lock);
if (itransfer->transferred < 0)
itransfer->transferred = 0;
return usbi_handle_transfer_cancellation(itransfer);
}
libusb_transfer_status status = LIBUSB_TRANSFER_COMPLETED;
- if(itransfer->transferred < 0)
- {
+ if (itransfer->transferred < 0) {
usbi_err(ITRANSFER_CTX(itransfer), "error in transfer");
status = LIBUSB_TRANSFER_ERROR;
- itransfer->transferred=0;
+ itransfer->transferred = 0;
}
delete transfer;
- *((USBTransfer**)usbi_transfer_get_os_priv(itransfer))=NULL;
+ *((USBTransfer **)usbi_transfer_get_os_priv(itransfer)) = NULL;
usbi_mutex_unlock(&itransfer->lock);
return usbi_handle_transfer_completion(itransfer, status);
}
static int
haiku_clock_gettime(int clkid, struct timespec *tp)
{
- if(clkid == USBI_CLOCK_REALTIME)
+ if (clkid == USBI_CLOCK_REALTIME)
return clock_gettime(CLOCK_REALTIME, tp);
- if(clkid == USBI_CLOCK_MONOTONIC)
+ if (clkid == USBI_CLOCK_MONOTONIC)
return clock_gettime(CLOCK_MONOTONIC, tp);
return LIBUSB_ERROR_INVALID_PARAM;
}
/*.get_timerfd_clockid =*/ NULL,
#endif
- /*.device_priv_size =*/ sizeof(USBDevice*),
- /*.device_handle_priv_size =*/ sizeof(USBDeviceHandle*),
- /*.transfer_priv_size =*/ sizeof(USBTransfer*),
+ /*.device_priv_size =*/ sizeof(USBDevice *),
+ /*.device_handle_priv_size =*/ sizeof(USBDeviceHandle *),
+ /*.transfer_priv_size =*/ sizeof(USBTransfer *),
};
typedef union {
struct {
- status_t status;
+ status_t status;
} version;
struct {
- status_t status;
- usb_device_descriptor *descriptor;
+ status_t status;
+ usb_device_descriptor *descriptor;
} device;
struct {
- status_t status;
- usb_configuration_descriptor *descriptor;
- uint32 config_index;
+ status_t status;
+ usb_configuration_descriptor *descriptor;
+ uint32 config_index;
} config;
struct {
- status_t status;
- uint32 alternate_info;
- uint32 config_index;
- uint32 interface_index;
+ status_t status;
+ uint32 alternate_info;
+ uint32 config_index;
+ uint32 interface_index;
} alternate;
struct {
- status_t status;
- usb_interface_descriptor *descriptor;
- uint32 config_index;
- uint32 interface_index;
+ status_t status;
+ usb_interface_descriptor *descriptor;
+ uint32 config_index;
+ uint32 interface_index;
} interface;
struct {
- status_t status;
- usb_interface_descriptor *descriptor;
- uint32 config_index;
- uint32 interface_index;
- uint32 alternate_index;
+ status_t status;
+ usb_interface_descriptor *descriptor;
+ uint32 config_index;
+ uint32 interface_index;
+ uint32 alternate_index;
} interface_etc;
struct {
- status_t status;
- usb_endpoint_descriptor *descriptor;
- uint32 config_index;
- uint32 interface_index;
- uint32 endpoint_index;
+ status_t status;
+ usb_endpoint_descriptor *descriptor;
+ uint32 config_index;
+ uint32 interface_index;
+ uint32 endpoint_index;
} endpoint;
struct {
- status_t status;
- usb_endpoint_descriptor *descriptor;
- uint32 config_index;
- uint32 interface_index;
- uint32 alternate_index;
- uint32 endpoint_index;
+ status_t status;
+ usb_endpoint_descriptor *descriptor;
+ uint32 config_index;
+ uint32 interface_index;
+ uint32 alternate_index;
+ uint32 endpoint_index;
} endpoint_etc;
struct {
- status_t status;
- usb_descriptor *descriptor;
- uint32 config_index;
- uint32 interface_index;
- uint32 generic_index;
- size_t length;
+ status_t status;
+ usb_descriptor *descriptor;
+ uint32 config_index;
+ uint32 interface_index;
+ uint32 generic_index;
+ size_t length;
} generic;
struct {
- status_t status;
- usb_descriptor *descriptor;
- uint32 config_index;
- uint32 interface_index;
- uint32 alternate_index;
- uint32 generic_index;
- size_t length;
+ status_t status;
+ usb_descriptor *descriptor;
+ uint32 config_index;
+ uint32 interface_index;
+ uint32 alternate_index;
+ uint32 generic_index;
+ size_t length;
} generic_etc;
struct {
- status_t status;
- usb_string_descriptor *descriptor;
- uint32 string_index;
- size_t length;
+ status_t status;
+ usb_string_descriptor *descriptor;
+ uint32 string_index;
+ size_t length;
} string;
struct {
- status_t status;
- uint8 type;
- uint8 index;
- uint16 language_id;
- void *data;
- size_t length;
+ status_t status;
+ uint8 type;
+ uint8 index;
+ uint16 language_id;
+ void *data;
+ size_t length;
} descriptor;
struct {
- status_t status;
- uint8 request_type;
- uint8 request;
- uint16 value;
- uint16 index;
- uint16 length;
- void *data;
+ status_t status;
+ uint8 request_type;
+ uint8 request;
+ uint16 value;
+ uint16 index;
+ uint16 length;
+ void *data;
} control;
struct {
- status_t status;
- uint32 interface;
- uint32 endpoint;
- void *data;
- size_t length;
+ status_t status;
+ uint32 interface;
+ uint32 endpoint;
+ void *data;
+ size_t length;
} transfer;
struct {
- status_t status;
- uint32 interface;
- uint32 endpoint;
- void *data;
- size_t length;
- usb_iso_packet_descriptor *packet_descriptors;
- uint32 packet_count;
+ status_t status;
+ uint32 interface;
+ uint32 endpoint;
+ void *data;
+ size_t length;
+ usb_iso_packet_descriptor *packet_descriptors;
+ uint32 packet_count;
} isochronous;
} usb_raw_command;
-#define LIBUSB_NANO 11017
+#define LIBUSB_NANO 11018