* Extend the usb_raw interface by alternate interface aware getters for

interfaces, endpoints and generic descriptors.
* Add getter for active interface index and simplify the count operation as
  it isn't misused to also get interface descriptors anymore.
* Refactor out some common code into helper functions.
* Adapt the USBKit to the changed/new interface.
* Change how alternate interfaces are exposed by USBKit by providing normal
  BUSBInterface objects for alternate interfaces that can easily be examined
  and used.
* Make BUSBInterface class aware of its alternate index and use the alternate
  aware usb_raw functionallity to build the endpoint and descriptor lists.
* Add ActiveAlternateIndex() to find out what alternate is currently active.
* Style cleanup of the USBKit classes, use std::nothrow everywhere and check
  all allocations. Simplify some code by removing optimization where the benefit
  is questionable.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@27409 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Michael Lotz
2008-09-10 21:52:32 +00:00
parent 44d0dbc898
commit 89dda28052
8 changed files with 455 additions and 299 deletions
+60 -48
View File
@@ -52,7 +52,7 @@ virtual void _ReservedUSBRoster3();
virtual void _ReservedUSBRoster4();
virtual void _ReservedUSBRoster5();
void *fLooper;
void * fLooper;
uint32 fReserved[10];
};
@@ -77,7 +77,7 @@ virtual status_t InitCheck();
void Unset();
// Returns the location on the bus represented as hub/device sequence
const char *Location() const;
const char * Location() const;
bool IsHub() const;
// These are direct accessors to descriptor fields
@@ -94,11 +94,12 @@ virtual status_t InitCheck();
// descriptor data. The strings are decoded to normal 0 terminated
// c strings and are cached and owned by the object.
// If a string is not available an empty string is returned.
const char *ManufacturerString() const;
const char *ProductString() const;
const char *SerialNumberString() const;
const char * ManufacturerString() const;
const char * ProductString() const;
const char * SerialNumberString() const;
const usb_device_descriptor *Descriptor() const;
const usb_device_descriptor *
Descriptor() const;
// GetStringDescriptor() can be used to retrieve the raw
// usb_string_descriptor with a given index. The strings contained
@@ -111,7 +112,7 @@ virtual status_t InitCheck();
// 0-terminated c string for a given string index. Note that this
// will allocate the string as "new char[];" and needs to be deleted
// like "delete[] string;" by the caller.
char *DecodeStringDescriptor(uint32 index) const;
char * DecodeStringDescriptor(uint32 index) const;
size_t GetDescriptor(uint8 type, uint8 index,
uint16 languageID, void *data,
@@ -124,9 +125,9 @@ virtual status_t InitCheck();
// Use the returned object as an argument to SetConfiguration() to
// change the active configuration of a device.
uint32 CountConfigurations() const;
const BUSBConfiguration *ConfigurationAt(uint32 index) const;
const BUSBConfiguration * ConfigurationAt(uint32 index) const;
const BUSBConfiguration *ActiveConfiguration() const;
const BUSBConfiguration * ActiveConfiguration() const;
status_t SetConfiguration(
const BUSBConfiguration *configuration);
@@ -143,16 +144,16 @@ virtual void _ReservedUSBDevice3();
virtual void _ReservedUSBDevice4();
virtual void _ReservedUSBDevice5();
char *fPath;
char * fPath;
int fRawFD;
usb_device_descriptor fDescriptor;
BUSBConfiguration **fConfigurations;
BUSBConfiguration ** fConfigurations;
uint32 fActiveConfiguration;
mutable char *fManufacturerString;
mutable char *fProductString;
mutable char *fSerialNumberString;
mutable char * fManufacturerString;
mutable char * fProductString;
mutable char * fSerialNumberString;
uint32 fReserved[10];
};
@@ -171,14 +172,14 @@ public:
// configuration is located at the index returned by Index() within
// that parent device.
uint32 Index() const;
const BUSBDevice *Device() const;
const BUSBDevice * Device() const;
// Gets a describing string of this configuration if available.
// Otherwise an empty string is returned.
const char *ConfigurationString() const;
const char * ConfigurationString() const;
const usb_configuration_descriptor
*Descriptor() const;
const usb_configuration_descriptor *
Descriptor() const;
// With CountInterfaces() and InterfaceAt() you can iterate through
// the child interfaces of this configuration. It is the only valid
@@ -186,7 +187,7 @@ public:
// Note that the interface objects retrieved using InterfaceAt() will
// be invalid and deleted as soon as this configuration gets deleted.
uint32 CountInterfaces() const;
const BUSBInterface *InterfaceAt(uint32 index) const;
const BUSBInterface * InterfaceAt(uint32 index) const;
private:
friend class BUSBDevice;
@@ -194,14 +195,14 @@ friend class BUSBDevice;
uint32 index, int rawFD);
~BUSBConfiguration();
BUSBDevice *fDevice;
BUSBDevice * fDevice;
uint32 fIndex;
int fRawFD;
usb_configuration_descriptor fDescriptor;
BUSBInterface **fInterfaces;
BUSBInterface ** fInterfaces;
mutable char *fConfigurationString;
mutable char * fConfigurationString;
uint32 fReserved[10];
};
@@ -215,12 +216,14 @@ class BUSBInterface {
public:
// Configuration() returns the parent configuration of this interface.
// This interface is located at the index returned by Index() in that
// parent configuration.
// parent configuration and represents the alternate interface returned
// by AlternateIndex().
// Device() is a convenience function to directly reach the parent
// device of this interface instead of going through the configuration.
uint32 Index() const;
const BUSBConfiguration *Configuration() const;
const BUSBDevice *Device() const;
uint32 AlternateIndex() const;
const BUSBConfiguration * Configuration() const;
const BUSBDevice * Device() const;
// These are accessors to descriptor fields. InterfaceString() tries
// to return a describing string of this interface. If no string is
@@ -228,10 +231,10 @@ public:
uint8 Class() const;
uint8 Subclass() const;
uint8 Protocol() const;
const char *InterfaceString() const;
const char * InterfaceString() const;
const usb_interface_descriptor
*Descriptor() const;
const usb_interface_descriptor *
Descriptor() const;
// Use OtherDescriptorAt() to get generic descriptors of an interface.
// These are usually vendor or device specific extensions.
@@ -244,7 +247,7 @@ public:
// valid way to get BUSBEndpoint object. Note that these objects will
// get invalid and deleted as soon as the parent interface is deleted.
uint32 CountEndpoints() const;
const BUSBEndpoint *EndpointAt(uint32 index) const;
const BUSBEndpoint * EndpointAt(uint32 index) const;
// Using CountAlternates() you can retrieve the number of alternate
// interfaces for this interface. Note that this interface itself
@@ -252,39 +255,47 @@ public:
// that you are currently using the sole interface present.
// AlternateAt() returns the interface descriptor of the alternate
// interface with the specified index. Using that you can peek at the
// information contained in the descriptor without having to switch
// to this alternate interface. Note that the alternate index set in
// the interface descriptor returned is not necessarily the same index
// you used to get the descriptor. Always use the zero based index you
// used to get the information with and not the values of the returned
// descriptor as the stack will handle that translation internally.
// The interface descriptor returned was allocated by new and is yours.
// You need to delete it when you're done with it.
// attributes of that alternate (including endpoints) without having to
// switch to this alternate interface.
// Note that you cannot use any endpoint you retrieve through an
// interface you get through AlternateAt(). Even if you switch to that
// alternate later on, you cannot use an interface returned by
// AlternateAt(). Instead switch to that alternate using the interface
// you got from the configuration and then use this switched interface
// to enumerate the endpoints.
// ActiveAlternateIndex() returns the index of the currently active
// alternate interface.
// With SetAlternate() you can switch this BUSBInterface object to the
// alternate interface at the specified index. Note that all endpoints
// retrieved through EndpointAt() will become invalid and will be
// deleted as soon as you set an alternate interface (even if the
// resulting interface is the same you were using before).
uint32 CountAlternates() const;
usb_interface_descriptor *AlternateAt(uint32 alternateIndex);
uint32 ActiveAlternateIndex() const;
const BUSBInterface * AlternateAt(uint32 alternateIndex) const;
status_t SetAlternate(uint32 alternateIndex);
private:
friend class BUSBConfiguration;
BUSBInterface(BUSBConfiguration *config,
uint32 index, int rawFD);
uint32 index, uint32 alternate,
int rawFD);
~BUSBInterface();
void _UpdateDescriptorAndEndpoints();
BUSBConfiguration *fConfiguration;
BUSBConfiguration * fConfiguration;
uint32 fIndex;
uint32 fAlternate;
int fRawFD;
usb_interface_descriptor fDescriptor;
BUSBEndpoint **fEndpoints;
BUSBEndpoint ** fEndpoints;
mutable char *fInterfaceString;
mutable uint32 fAlternateCount;
mutable BUSBInterface ** fAlternates;
mutable char * fInterfaceString;
uint32 fReserved[10];
};
@@ -302,9 +313,9 @@ public:
// reach the parent configuration or device of this endpoint instead
// of going through the parent objects.
uint32 Index() const;
const BUSBInterface *Interface() const;
const BUSBConfiguration *Configuration() const;
const BUSBDevice *Device() const;
const BUSBInterface * Interface() const;
const BUSBConfiguration * Configuration() const;
const BUSBDevice * Device() const;
// These methods can be used to check for endpoint characteristics.
bool IsBulk() const;
@@ -318,8 +329,8 @@ public:
uint16 MaxPacketSize() const;
uint8 Interval() const;
const usb_endpoint_descriptor
*Descriptor() const;
const usb_endpoint_descriptor *
Descriptor() const;
// These methods initiate transfers to or from the endpoint. All
// transfers are synchronous and the actually transfered amount of
@@ -343,13 +354,14 @@ public:
// send the corresponding requests.
bool IsStalled() const;
status_t ClearStall() const;
private:
friend class BUSBInterface;
BUSBEndpoint(BUSBInterface *interface,
uint32 index, int rawFD);
~BUSBEndpoint();
BUSBInterface *fInterface;
BUSBInterface * fInterface;
uint32 fIndex;
int fRawFD;
+172 -138
View File
@@ -124,6 +124,58 @@ usb_raw_device_removed(void *cookie)
//
static const usb_configuration_info *
usb_raw_get_configuration(raw_device *device, uint32 configIndex,
status_t *status)
{
const usb_configuration_info *result = gUSBModule->get_nth_configuration(
device->device, configIndex);
if (result == NULL) {
*status = B_USB_RAW_STATUS_INVALID_CONFIGURATION;
return NULL;
}
return result;
}
static const usb_interface_info *
usb_raw_get_interface(raw_device *device, uint32 configIndex,
uint32 interfaceIndex, uint32 alternateIndex, status_t *status)
{
const usb_configuration_info *configurationInfo
= usb_raw_get_configuration(device, configIndex, status);
if (configurationInfo == NULL)
return NULL;
if (interfaceIndex >= configurationInfo->interface_count) {
*status = B_USB_RAW_STATUS_INVALID_INTERFACE;
return NULL;
}
const usb_interface_info *result = NULL;
if (alternateIndex == B_USB_RAW_ACTIVE_ALTERNATE)
result = configurationInfo->interface[interfaceIndex].active;
else {
const usb_interface_list *interfaceList =
&configurationInfo->interface[interfaceIndex];
if (alternateIndex >= interfaceList->alt_count) {
*status = B_USB_RAW_STATUS_INVALID_INTERFACE;
return NULL;
}
result = &interfaceList->alt[alternateIndex];
}
return result;
}
//
//#pragma mark -
//
static status_t
usb_raw_open(const char *name, uint32 flags, void **cookie)
{
@@ -211,11 +263,12 @@ usb_raw_ioctl(void *cookie, uint32 op, void *buffer, size_t length)
{
TRACE((DRIVER_NAME": ioctl\n"));
raw_device *device = (raw_device *)cookie;
usb_raw_command *command = (usb_raw_command *)buffer;
if (device->device == 0)
return B_DEV_NOT_READY;
usb_raw_command *command = (usb_raw_command *)buffer;
command->version.status = B_USB_RAW_STATUS_ABORTED;
switch (op) {
case B_USB_RAW_COMMAND_GET_VERSION: {
command->version.status = B_USB_RAW_PROTOCOL_VERSION;
@@ -225,10 +278,8 @@ usb_raw_ioctl(void *cookie, uint32 op, void *buffer, size_t length)
case B_USB_RAW_COMMAND_GET_DEVICE_DESCRIPTOR: {
const usb_device_descriptor *deviceDescriptor =
gUSBModule->get_device_descriptor(device->device);
if (!deviceDescriptor) {
command->device.status = B_USB_RAW_STATUS_ABORTED;
if (!deviceDescriptor)
return B_OK;
}
memcpy(command->device.descriptor, deviceDescriptor,
sizeof(usb_device_descriptor));
@@ -238,12 +289,10 @@ usb_raw_ioctl(void *cookie, uint32 op, void *buffer, size_t length)
case B_USB_RAW_COMMAND_GET_CONFIGURATION_DESCRIPTOR: {
const usb_configuration_info *configurationInfo =
gUSBModule->get_nth_configuration(device->device,
command->config.config_index);
if (!configurationInfo) {
command->config.status = B_USB_RAW_STATUS_INVALID_CONFIGURATION;
usb_raw_get_configuration(device, command->config.config_index,
&command->config.status);
if (configurationInfo == NULL)
return B_OK;
}
memcpy(command->config.descriptor, configurationInfo->descr,
sizeof(usb_configuration_descriptor));
@@ -251,155 +300,142 @@ usb_raw_ioctl(void *cookie, uint32 op, void *buffer, size_t length)
return B_OK;
}
case B_USB_RAW_COMMAND_GET_INTERFACE_DESCRIPTOR: {
case B_USB_RAW_COMMAND_GET_ALT_INTERFACE_COUNT:
case B_USB_RAW_COMMAND_GET_ACTIVE_ALT_INTERFACE_INDEX: {
const usb_configuration_info *configurationInfo =
gUSBModule->get_nth_configuration(device->device,
command->interface.config_index);
if (!configurationInfo) {
command->interface.status = B_USB_RAW_STATUS_INVALID_CONFIGURATION;
usb_raw_get_configuration(device,
command->alternate.config_index,
&command->alternate.status);
if (configurationInfo == NULL)
return B_OK;
if (command->alternate.interface_index
>= configurationInfo->interface_count) {
command->alternate.status = B_USB_RAW_STATUS_INVALID_INTERFACE;
return B_OK;
}
if (command->interface.interface_index >= configurationInfo->interface_count) {
command->interface.status = B_USB_RAW_STATUS_INVALID_INTERFACE;
return B_OK;
const usb_interface_list *interfaceList
= &configurationInfo->interface[
command->alternate.interface_index];
if (op == B_USB_RAW_COMMAND_GET_ALT_INTERFACE_COUNT) {
command->alternate.alternate_info = interfaceList->alt_count;
} else {
for (size_t i = 0; i < interfaceList->alt_count; i++) {
if (&interfaceList->alt[i] == interfaceList->active) {
command->alternate.alternate_info = i;
break;
}
}
}
const usb_interface_info *interfaceInfo =
configurationInfo->interface[command->interface.interface_index].active;
if (!interfaceInfo) {
command->interface.status = B_USB_RAW_STATUS_ABORTED;
return B_OK;
command->alternate.status = B_USB_RAW_STATUS_SUCCESS;
return B_OK;
}
case B_USB_RAW_COMMAND_GET_INTERFACE_DESCRIPTOR:
case B_USB_RAW_COMMAND_GET_INTERFACE_DESCRIPTOR_ETC: {
const usb_interface_info *interfaceInfo = NULL;
if (op == B_USB_RAW_COMMAND_GET_INTERFACE_DESCRIPTOR) {
interfaceInfo = usb_raw_get_interface(device,
command->interface.config_index,
command->interface.interface_index,
B_USB_RAW_ACTIVE_ALTERNATE,
&command->interface.status);
} else {
interfaceInfo = usb_raw_get_interface(device,
command->interface_etc.config_index,
command->interface_etc.interface_index,
command->interface_etc.alternate_index,
&command->interface_etc.status);
}
if (interfaceInfo == NULL)
return B_OK;
memcpy(command->interface.descriptor, interfaceInfo->descr,
sizeof(usb_interface_descriptor));
command->interface.status = B_USB_RAW_STATUS_SUCCESS;
return B_OK;
}
case B_USB_RAW_COMMAND_GET_ALT_INTERFACE_COUNT: {
const usb_configuration_info *configurationInfo =
gUSBModule->get_nth_configuration(device->device,
command->alternate.config_index);
if (!configurationInfo) {
command->alternate.status = B_USB_RAW_STATUS_INVALID_CONFIGURATION;
return B_OK;
case B_USB_RAW_COMMAND_GET_ENDPOINT_DESCRIPTOR:
case B_USB_RAW_COMMAND_GET_ENDPOINT_DESCRIPTOR_ETC: {
uint32 endpointIndex = 0;
const usb_interface_info *interfaceInfo = NULL;
if (op == B_USB_RAW_COMMAND_GET_ENDPOINT_DESCRIPTOR) {
interfaceInfo = usb_raw_get_interface(device,
command->endpoint.config_index,
command->endpoint.interface_index,
B_USB_RAW_ACTIVE_ALTERNATE,
&command->endpoint.status);
endpointIndex = command->endpoint.endpoint_index;
} else {
interfaceInfo = usb_raw_get_interface(device,
command->endpoint_etc.config_index,
command->endpoint_etc.interface_index,
command->endpoint_etc.alternate_index,
&command->endpoint_etc.status);
endpointIndex = command->endpoint_etc.endpoint_index;
}
if (command->alternate.interface_index >= configurationInfo->interface_count) {
command->alternate.status = B_USB_RAW_STATUS_INVALID_INTERFACE;
if (!interfaceInfo)
return B_OK;
}
*command->alternate.alternate_count
= configurationInfo->interface[command->alternate.interface_index].alt_count;
command->alternate.status = B_USB_RAW_STATUS_SUCCESS;
return B_OK;
}
case B_USB_RAW_COMMAND_GET_ALT_INTERFACE_DESCRIPTOR: {
const usb_configuration_info *configurationInfo =
gUSBModule->get_nth_configuration(device->device,
command->alternate.config_index);
if (!configurationInfo) {
command->alternate.status = B_USB_RAW_STATUS_INVALID_CONFIGURATION;
return B_OK;
}
if (command->alternate.interface_index >= configurationInfo->interface_count) {
command->alternate.status = B_USB_RAW_STATUS_INVALID_INTERFACE;
return B_OK;
}
const usb_interface_list *interfaceList =
&configurationInfo->interface[command->alternate.interface_index];
if (command->alternate.alternate_index >= interfaceList->alt_count) {
command->alternate.status = B_USB_RAW_STATUS_INVALID_INTERFACE;
return B_OK;
}
memcpy(command->alternate.descriptor,
&interfaceList->alt[command->alternate.alternate_index],
sizeof(usb_interface_descriptor));
command->alternate.status = B_USB_RAW_STATUS_SUCCESS;
return B_OK;
}
case B_USB_RAW_COMMAND_GET_ENDPOINT_DESCRIPTOR: {
const usb_configuration_info *configurationInfo =
gUSBModule->get_nth_configuration(device->device,
command->endpoint.config_index);
if (!configurationInfo) {
command->endpoint.status = B_USB_RAW_STATUS_INVALID_CONFIGURATION;
return B_OK;
}
if (command->endpoint.interface_index >= configurationInfo->interface_count) {
command->endpoint.status = B_USB_RAW_STATUS_INVALID_INTERFACE;
return B_OK;
}
const usb_interface_info *interfaceInfo =
configurationInfo->interface[command->endpoint.interface_index].active;
if (!interfaceInfo) {
command->endpoint.status = B_USB_RAW_STATUS_ABORTED;
return B_OK;
}
if (command->endpoint.endpoint_index >= interfaceInfo->endpoint_count) {
if (endpointIndex >= interfaceInfo->endpoint_count) {
command->endpoint.status = B_USB_RAW_STATUS_INVALID_ENDPOINT;
return B_OK;
}
memcpy(command->endpoint.descriptor,
interfaceInfo->endpoint[command->endpoint.endpoint_index].descr,
interfaceInfo->endpoint[endpointIndex].descr,
sizeof(usb_endpoint_descriptor));
command->endpoint.status = B_USB_RAW_STATUS_SUCCESS;
return B_OK;
}
case B_USB_RAW_COMMAND_GET_GENERIC_DESCRIPTOR: {
const usb_configuration_info *configurationInfo =
gUSBModule->get_nth_configuration(device->device,
command->generic.config_index);
if (!configurationInfo) {
command->generic.status = B_USB_RAW_STATUS_INVALID_CONFIGURATION;
case B_USB_RAW_COMMAND_GET_GENERIC_DESCRIPTOR:
case B_USB_RAW_COMMAND_GET_GENERIC_DESCRIPTOR_ETC: {
uint32 genericIndex = 0;
size_t genericLength = 0;
const usb_interface_info *interfaceInfo = NULL;
if (op == B_USB_RAW_COMMAND_GET_GENERIC_DESCRIPTOR) {
interfaceInfo = usb_raw_get_interface(device,
command->generic.config_index,
command->generic.interface_index,
B_USB_RAW_ACTIVE_ALTERNATE,
&command->generic.status);
genericIndex = command->generic.generic_index;
genericLength = command->generic.length;
} else {
interfaceInfo = usb_raw_get_interface(device,
command->generic_etc.config_index,
command->generic_etc.interface_index,
command->generic_etc.alternate_index,
&command->generic_etc.status);
genericIndex = command->generic_etc.generic_index;
genericLength = command->generic_etc.length;
}
if (!interfaceInfo)
return B_OK;
if (genericIndex >= interfaceInfo->generic_count) {
command->endpoint.status = B_USB_RAW_STATUS_INVALID_ENDPOINT;
return B_OK;
}
if (command->generic.interface_index >= configurationInfo->interface_count) {
command->generic.status = B_USB_RAW_STATUS_INVALID_INTERFACE;
usb_descriptor *descriptor = interfaceInfo->generic[genericIndex];
if (!descriptor)
return B_OK;
}
const usb_interface_info *interfaceInfo =
configurationInfo->interface[command->generic.interface_index].active;
if (!interfaceInfo) {
command->generic.status = B_USB_RAW_STATUS_ABORTED;
return B_OK;
}
if (command->generic.generic_index >= interfaceInfo->generic_count) {
// ToDo: add B_USB_RAW_STATUS_INVALID_GENERIC
command->generic.status = B_USB_RAW_STATUS_INVALID_ENDPOINT;
return B_OK;
}
usb_descriptor *descriptor = interfaceInfo->generic[command->generic.generic_index];
if (!descriptor) {
command->generic.status = B_USB_RAW_STATUS_ABORTED;
return B_OK;
}
if (descriptor->generic.length > command->generic.length) {
command->generic.status = B_USB_RAW_STATUS_NO_MEMORY;
return B_OK;
}
memcpy(command->generic.descriptor, descriptor,
descriptor->generic.length);
command->generic.status = B_USB_RAW_STATUS_SUCCESS;
min_c(genericLength, descriptor->generic.length));
if (descriptor->generic.length > genericLength)
command->generic.status = B_USB_RAW_STATUS_NO_MEMORY;
else
command->generic.status = B_USB_RAW_STATUS_SUCCESS;
return B_OK;
}
@@ -485,12 +521,10 @@ usb_raw_ioctl(void *cookie, uint32 op, void *buffer, size_t length)
case B_USB_RAW_COMMAND_SET_CONFIGURATION: {
const usb_configuration_info *configurationInfo =
gUSBModule->get_nth_configuration(device->device,
command->config.config_index);
if (!configurationInfo) {
command->config.status = B_USB_RAW_STATUS_INVALID_CONFIGURATION;
usb_raw_get_configuration(device, command->config.config_index,
&command->config.status);
if (configurationInfo == NULL)
return B_OK;
}
if (gUSBModule->set_configuration(device->device,
configurationInfo) < B_OK) {
@@ -504,27 +538,27 @@ usb_raw_ioctl(void *cookie, uint32 op, void *buffer, size_t length)
case B_USB_RAW_COMMAND_SET_ALT_INTERFACE: {
const usb_configuration_info *configurationInfo =
gUSBModule->get_nth_configuration(device->device,
command->alternate.config_index);
if (!configurationInfo) {
command->alternate.status = B_USB_RAW_STATUS_INVALID_CONFIGURATION;
usb_raw_get_configuration(device,
command->alternate.config_index,
&command->alternate.status);
if (configurationInfo == NULL)
return B_OK;
}
if (command->alternate.interface_index >= configurationInfo->interface_count) {
if (command->alternate.interface_index
>= configurationInfo->interface_count) {
command->alternate.status = B_USB_RAW_STATUS_INVALID_INTERFACE;
return B_OK;
}
const usb_interface_list *interfaceList =
&configurationInfo->interface[command->alternate.interface_index];
if (command->alternate.alternate_index >= interfaceList->alt_count) {
if (command->alternate.alternate_info >= interfaceList->alt_count) {
command->alternate.status = B_USB_RAW_STATUS_INVALID_INTERFACE;
return B_OK;
}
if (gUSBModule->set_alt_interface(device->device,
&interfaceList->alt[command->alternate.alternate_index]) < B_OK) {
&interfaceList->alt[command->alternate.alternate_info]) < B_OK) {
command->alternate.status = B_USB_RAW_STATUS_FAILED;
return B_OK;
}
+36 -7
View File
@@ -9,6 +9,7 @@
#include <USB3.h>
#define B_USB_RAW_PROTOCOL_VERSION 0x0015
#define B_USB_RAW_ACTIVE_ALTERNATE 0xffffffff
typedef enum {
B_USB_RAW_COMMAND_GET_VERSION = 0x1000,
@@ -20,7 +21,10 @@ typedef enum {
B_USB_RAW_COMMAND_GET_STRING_DESCRIPTOR,
B_USB_RAW_COMMAND_GET_GENERIC_DESCRIPTOR,
B_USB_RAW_COMMAND_GET_ALT_INTERFACE_COUNT,
B_USB_RAW_COMMAND_GET_ALT_INTERFACE_DESCRIPTOR,
B_USB_RAW_COMMAND_GET_ACTIVE_ALT_INTERFACE_INDEX,
B_USB_RAW_COMMAND_GET_INTERFACE_DESCRIPTOR_ETC,
B_USB_RAW_COMMAND_GET_ENDPOINT_DESCRIPTOR_ETC,
B_USB_RAW_COMMAND_GET_GENERIC_DESCRIPTOR_ETC,
B_USB_RAW_COMMAND_SET_CONFIGURATION = 0x3000,
B_USB_RAW_COMMAND_SET_FEATURE,
@@ -70,6 +74,13 @@ typedef union {
uint32 config_index;
} config;
struct {
status_t status;
uint32 alternate_info;
uint32 config_index;
uint32 interface_index;
} alternate;
struct {
status_t status;
usb_interface_descriptor *descriptor;
@@ -79,12 +90,11 @@ typedef union {
struct {
status_t status;
uint32 *alternate_count;
usb_interface_descriptor *descriptor;
uint32 config_index;
uint32 interface_index;
uint32 alternate_index;
} alternate;
} interface_etc;
struct {
status_t status;
@@ -96,10 +106,12 @@ typedef union {
struct {
status_t status;
usb_string_descriptor *descriptor;
uint32 string_index;
size_t length;
} string;
usb_endpoint_descriptor *descriptor;
uint32 config_index;
uint32 interface_index;
uint32 alternate_index;
uint32 endpoint_index;
} endpoint_etc;
struct {
status_t status;
@@ -110,6 +122,23 @@ typedef union {
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;
} generic_etc;
struct {
status_t status;
usb_string_descriptor *descriptor;
uint32 string_index;
size_t length;
} string;
struct {
status_t status;
uint8 type;
+21 -13
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2007, Haiku Inc. All rights reserved.
* Copyright 2007-2008, Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
@@ -10,6 +10,7 @@
#include <usb_raw.h>
#include <unistd.h>
#include <string.h>
#include <new>
BUSBConfiguration::BUSBConfiguration(BUSBDevice *device, uint32 index, int rawFD)
@@ -26,18 +27,26 @@ BUSBConfiguration::BUSBConfiguration(BUSBDevice *device, uint32 index, int rawFD
sizeof(command)) || command.config.status != B_USB_RAW_STATUS_SUCCESS)
memset(&fDescriptor, 0, sizeof(fDescriptor));
fInterfaces = new BUSBInterface *[fDescriptor.number_interfaces];
for (uint32 i = 0; i < fDescriptor.number_interfaces; i++)
fInterfaces[i] = new BUSBInterface(this, i, fRawFD);
fInterfaces = new(std::nothrow) BUSBInterface *[
fDescriptor.number_interfaces];
if (fInterfaces == NULL)
return;
for (uint32 i = 0; i < fDescriptor.number_interfaces; i++) {
fInterfaces[i] = new(std::nothrow) BUSBInterface(this, i,
B_USB_RAW_ACTIVE_ALTERNATE, fRawFD);
}
}
BUSBConfiguration::~BUSBConfiguration()
{
delete[] fConfigurationString;
for (int32 i = 0; i < fDescriptor.number_interfaces; i++)
delete fInterfaces[i];
delete[] fInterfaces;
if (fInterfaces != NULL) {
for (int32 i = 0; i < fDescriptor.number_interfaces; i++)
delete fInterfaces[i];
delete[] fInterfaces;
}
}
@@ -64,11 +73,10 @@ BUSBConfiguration::ConfigurationString() const
if (fConfigurationString)
return fConfigurationString;
fConfigurationString = Device()->DecodeStringDescriptor(fDescriptor.configuration);
if (!fConfigurationString) {
fConfigurationString = new char[1];
fConfigurationString[0] = 0;
}
fConfigurationString = Device()->DecodeStringDescriptor(
fDescriptor.configuration);
if (fConfigurationString == NULL)
return "";
return fConfigurationString;
}
@@ -91,7 +99,7 @@ BUSBConfiguration::CountInterfaces() const
const BUSBInterface *
BUSBConfiguration::InterfaceAt(uint32 index) const
{
if (index >= fDescriptor.number_interfaces)
if (index >= fDescriptor.number_interfaces || fInterfaces == NULL)
return NULL;
return fInterfaces[index];
+33 -22
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2007, Haiku Inc. All rights reserved.
* Copyright 2007-2008, Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
@@ -8,9 +8,10 @@
#include <USBKit.h>
#include <usb_raw.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <malloc.h>
#include <new>
BUSBDevice::BUSBDevice(const char *path)
@@ -69,9 +70,15 @@ BUSBDevice::SetTo(const char *path)
return B_ERROR;
}
fConfigurations = new BUSBConfiguration *[fDescriptor.num_configurations];
for (uint32 i = 0; i < fDescriptor.num_configurations; i++)
fConfigurations[i] = new BUSBConfiguration(this, i, fRawFD);
fConfigurations = new(std::nothrow) BUSBConfiguration *[
fDescriptor.num_configurations];
if (fConfigurations == NULL)
return B_NO_MEMORY;
for (uint32 i = 0; i < fDescriptor.num_configurations; i++) {
fConfigurations[i] = new(std::nothrow) BUSBConfiguration(this, i,
fRawFD);
}
return B_OK;
}
@@ -92,10 +99,14 @@ BUSBDevice::Unset()
delete[] fSerialNumberString;
fManufacturerString = fProductString = fSerialNumberString = NULL;
for (int32 i = 0; i < fDescriptor.num_configurations; i++)
delete fConfigurations[i];
if (fConfigurations != NULL) {
for (int32 i = 0; i < fDescriptor.num_configurations; i++)
delete fConfigurations[i];
delete[] fConfigurations;
fConfigurations = NULL;
}
delete[] fConfigurations;
memset(&fDescriptor, 0, sizeof(fDescriptor));
}
@@ -183,10 +194,8 @@ BUSBDevice::ManufacturerString() const
return fManufacturerString;
fManufacturerString = DecodeStringDescriptor(fDescriptor.manufacturer);
if (!fManufacturerString) {
fManufacturerString = new char[1];
fManufacturerString[0] = 0;
}
if (fManufacturerString == NULL)
return "";
return fManufacturerString;
}
@@ -202,10 +211,8 @@ BUSBDevice::ProductString() const
return fProductString;
fProductString = DecodeStringDescriptor(fDescriptor.product);
if (!fProductString) {
fProductString = new char[1];
fProductString[0] = 0;
}
if (fProductString == NULL)
return "";
return fProductString;
}
@@ -221,10 +228,8 @@ BUSBDevice::SerialNumberString() const
return fSerialNumberString;
fSerialNumberString = DecodeStringDescriptor(fDescriptor.serial_number);
if (!fSerialNumberString) {
fSerialNumberString = new char[1];
fSerialNumberString[0] = 0;
}
if (fSerialNumberString == NULL)
return "";
return fSerialNumberString;
}
@@ -272,7 +277,10 @@ BUSBDevice::DecodeStringDescriptor(uint32 index) const
// pseudo convert unicode string
stringLength = (stringLength - 2) / 2;
char *result = new char[stringLength + 1];
char *result = new(std::nothrow) char[stringLength + 1];
if (result == NULL)
return NULL;
for (size_t i = 0; i < stringLength; i++)
result[i] = stringDescriptor->string[i * 2];
result[stringLength] = 0;
@@ -312,7 +320,7 @@ BUSBDevice::CountConfigurations() const
const BUSBConfiguration *
BUSBDevice::ConfigurationAt(uint32 index) const
{
if (index >= fDescriptor.num_configurations)
if (index >= fDescriptor.num_configurations && fConfigurations != NULL)
return NULL;
return fConfigurations[index];
@@ -322,6 +330,9 @@ BUSBDevice::ConfigurationAt(uint32 index) const
const BUSBConfiguration *
BUSBDevice::ActiveConfiguration() const
{
if (fConfigurations == NULL)
return NULL;
return fConfigurations[fActiveConfiguration];
}
+19 -12
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2007, Haiku Inc. All rights reserved.
* Copyright 2007-2008, Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
@@ -18,11 +18,12 @@ BUSBEndpoint::BUSBEndpoint(BUSBInterface *interface, uint32 index, int rawFD)
fRawFD(rawFD)
{
usb_raw_command command;
command.endpoint.descriptor = &fDescriptor;
command.endpoint.config_index = fInterface->Configuration()->Index();
command.endpoint.interface_index = fInterface->Index();
command.endpoint.endpoint_index = fIndex;
if (ioctl(fRawFD, B_USB_RAW_COMMAND_GET_ENDPOINT_DESCRIPTOR, &command,
command.endpoint_etc.descriptor = &fDescriptor;
command.endpoint_etc.config_index = fInterface->Configuration()->Index();
command.endpoint_etc.interface_index = fInterface->Index();
command.endpoint_etc.alternate_index = fInterface->AlternateIndex();
command.endpoint_etc.endpoint_index = fIndex;
if (ioctl(fRawFD, B_USB_RAW_COMMAND_GET_ENDPOINT_DESCRIPTOR_ETC, &command,
sizeof(command)) || command.config.status != B_USB_RAW_STATUS_SUCCESS)
memset(&fDescriptor, 0, sizeof(fDescriptor));
}
@@ -64,42 +65,48 @@ BUSBEndpoint::Device() const
bool
BUSBEndpoint::IsBulk() const
{
return (fDescriptor.attributes & USB_ENDPOINT_ATTR_MASK) == USB_ENDPOINT_ATTR_BULK;
return (fDescriptor.attributes & USB_ENDPOINT_ATTR_MASK)
== USB_ENDPOINT_ATTR_BULK;
}
bool
BUSBEndpoint::IsInterrupt() const
{
return (fDescriptor.attributes & USB_ENDPOINT_ATTR_MASK) == USB_ENDPOINT_ATTR_INTERRUPT;
return (fDescriptor.attributes & USB_ENDPOINT_ATTR_MASK)
== USB_ENDPOINT_ATTR_INTERRUPT;
}
bool
BUSBEndpoint::IsIsochronous() const
{
return (fDescriptor.attributes & USB_ENDPOINT_ATTR_MASK) == USB_ENDPOINT_ATTR_ISOCHRONOUS;
return (fDescriptor.attributes & USB_ENDPOINT_ATTR_MASK)
== USB_ENDPOINT_ATTR_ISOCHRONOUS;
}
bool
BUSBEndpoint::IsControl() const
{
return (fDescriptor.attributes & USB_ENDPOINT_ATTR_MASK) == USB_ENDPOINT_ATTR_CONTROL;
return (fDescriptor.attributes & USB_ENDPOINT_ATTR_MASK)
== USB_ENDPOINT_ATTR_CONTROL;
}
bool
BUSBEndpoint::IsInput() const
{
return (fDescriptor.endpoint_address & USB_ENDPOINT_ADDR_DIR_IN) == USB_ENDPOINT_ADDR_DIR_IN;
return (fDescriptor.endpoint_address & USB_ENDPOINT_ADDR_DIR_IN)
== USB_ENDPOINT_ADDR_DIR_IN;
}
bool
BUSBEndpoint::IsOutput() const
{
return (fDescriptor.endpoint_address & USB_ENDPOINT_ADDR_DIR_IN) == USB_ENDPOINT_ADDR_DIR_OUT;
return (fDescriptor.endpoint_address & USB_ENDPOINT_ADDR_DIR_IN)
== USB_ENDPOINT_ADDR_DIR_OUT;
}
+83 -41
View File
@@ -15,11 +15,15 @@
#include <unistd.h>
BUSBInterface::BUSBInterface(BUSBConfiguration *config, uint32 index, int rawFD)
BUSBInterface::BUSBInterface(BUSBConfiguration *config, uint32 index,
uint32 alternate, int rawFD)
: fConfiguration(config),
fIndex(index),
fAlternate(alternate),
fRawFD(rawFD),
fEndpoints(NULL),
fAlternateCount(0),
fAlternates(NULL),
fInterfaceString(NULL)
{
_UpdateDescriptorAndEndpoints();
@@ -29,9 +33,18 @@ BUSBInterface::BUSBInterface(BUSBConfiguration *config, uint32 index, int rawFD)
BUSBInterface::~BUSBInterface()
{
delete[] fInterfaceString;
for (int32 i = 0; i < fDescriptor.num_endpoints; i++)
delete fEndpoints[i];
delete[] fEndpoints;
if (fEndpoints != NULL) {
for (int32 i = 0; i < fDescriptor.num_endpoints; i++)
delete fEndpoints[i];
delete[] fEndpoints;
}
if (fAlternates != NULL) {
for (uint32 i = 0; i < fAlternateCount; i++)
delete fAlternates[i];
delete[] fAlternates;
}
}
@@ -42,6 +55,15 @@ BUSBInterface::Index() const
}
uint32
BUSBInterface::AlternateIndex() const
{
if (fAlternate == B_USB_RAW_ACTIVE_ALTERNATE)
return ActiveAlternateIndex();
return fAlternate;
}
const BUSBConfiguration *
BUSBInterface::Configuration() const
{
@@ -87,10 +109,8 @@ BUSBInterface::InterfaceString() const
return fInterfaceString;
fInterfaceString = Device()->DecodeStringDescriptor(fDescriptor.interface);
if (!fInterfaceString) {
fInterfaceString = new char[1];
fInterfaceString[0] = 0;
}
if (fInterfaceString == NULL)
return "";
return fInterfaceString;
}
@@ -111,11 +131,12 @@ BUSBInterface::OtherDescriptorAt(uint32 index, usb_descriptor *descriptor,
return B_BAD_VALUE;
usb_raw_command command;
command.generic.descriptor = descriptor;
command.generic.config_index = fConfiguration->Index();
command.generic.interface_index = fIndex;
command.generic.length = length;
command.generic.generic_index = index;
command.generic_etc.descriptor = descriptor;
command.generic_etc.config_index = fConfiguration->Index();
command.generic_etc.interface_index = fIndex;
command.generic_etc.alternate_index = fAlternate;
command.generic_etc.generic_index = index;
command.generic_etc.length = length;
if (ioctl(fRawFD, B_USB_RAW_COMMAND_GET_GENERIC_DESCRIPTOR, &command,
sizeof(command)) || command.generic.status != B_USB_RAW_STATUS_SUCCESS)
return B_ERROR;
@@ -134,7 +155,7 @@ BUSBInterface::CountEndpoints() const
const BUSBEndpoint *
BUSBInterface::EndpointAt(uint32 index) const
{
if (index >= fDescriptor.num_endpoints)
if (index >= fDescriptor.num_endpoints && fEndpoints != NULL)
return NULL;
return fEndpoints[index];
@@ -144,39 +165,56 @@ BUSBInterface::EndpointAt(uint32 index) const
uint32
BUSBInterface::CountAlternates() const
{
uint32 alternateCount;
usb_raw_command command;
command.alternate.alternate_count = &alternateCount;
command.alternate.config_index = fConfiguration->Index();
command.alternate.interface_index = fIndex;
if (ioctl(fRawFD, B_USB_RAW_COMMAND_GET_ALT_INTERFACE_COUNT, &command,
sizeof(command)) || command.alternate.status != B_USB_RAW_STATUS_SUCCESS)
return 1;
return alternateCount;
return command.alternate.alternate_info;
}
usb_interface_descriptor *
BUSBInterface::AlternateAt(uint32 alternateIndex)
const BUSBInterface *
BUSBInterface::AlternateAt(uint32 alternateIndex) const
{
usb_interface_descriptor *descriptor
= new(std::nothrow) usb_interface_descriptor;
if (descriptor == NULL)
return NULL;
if (fAlternateCount > 0 && fAlternates != NULL) {
if (alternateIndex >= fAlternateCount)
return NULL;
usb_raw_command command;
command.alternate.descriptor = descriptor;
command.alternate.config_index = fConfiguration->Index();
command.alternate.interface_index = fIndex;
command.alternate.alternate_index = alternateIndex;
if (ioctl(fRawFD, B_USB_RAW_COMMAND_GET_ALT_INTERFACE_DESCRIPTOR, &command,
sizeof(command)) || command.alternate.status != B_USB_RAW_STATUS_SUCCESS) {
delete descriptor;
return NULL;
return fAlternates[alternateIndex];
}
return descriptor;
if (fAlternateCount == 0)
fAlternateCount = CountAlternates();
if (alternateIndex >= fAlternateCount)
return NULL;
fAlternates = new(std::nothrow) BUSBInterface *[fAlternateCount];
if (fAlternates == NULL)
return NULL;
for (uint32 i = 0; i < fAlternateCount; i++) {
fAlternates[i] = new(std::nothrow) BUSBInterface(fConfiguration, fIndex,
i, fRawFD);
}
return fAlternates[alternateIndex];
}
uint32
BUSBInterface::ActiveAlternateIndex() const
{
usb_raw_command command;
command.alternate.config_index = fConfiguration->Index();
command.alternate.interface_index = fIndex;
if (ioctl(fRawFD, B_USB_RAW_COMMAND_GET_ACTIVE_ALT_INTERFACE_INDEX, &command,
sizeof(command)) || command.alternate.status != B_USB_RAW_STATUS_SUCCESS)
return 0;
return command.alternate.alternate_info;
}
@@ -184,9 +222,9 @@ status_t
BUSBInterface::SetAlternate(uint32 alternateIndex)
{
usb_raw_command command;
command.alternate.alternate_info = alternateIndex;
command.alternate.config_index = fConfiguration->Index();
command.alternate.interface_index = fIndex;
command.alternate.alternate_index = alternateIndex;
if (ioctl(fRawFD, B_USB_RAW_COMMAND_SET_ALT_INTERFACE, &command,
sizeof(command)) || command.alternate.status != B_USB_RAW_STATUS_SUCCESS)
return B_ERROR;
@@ -200,21 +238,25 @@ void
BUSBInterface::_UpdateDescriptorAndEndpoints()
{
usb_raw_command command;
command.interface.descriptor = &fDescriptor;
command.interface.config_index = fConfiguration->Index();
command.interface.interface_index = fIndex;
if (ioctl(fRawFD, B_USB_RAW_COMMAND_GET_INTERFACE_DESCRIPTOR, &command,
command.interface_etc.descriptor = &fDescriptor;
command.interface_etc.config_index = fConfiguration->Index();
command.interface_etc.interface_index = fIndex;
command.interface_etc.alternate_index = fAlternate;
if (ioctl(fRawFD, B_USB_RAW_COMMAND_GET_INTERFACE_DESCRIPTOR_ETC, &command,
sizeof(command)) || command.interface.status != B_USB_RAW_STATUS_SUCCESS)
memset(&fDescriptor, 0, sizeof(fDescriptor));
if (fEndpoints) {
if (fEndpoints != NULL) {
// Delete old endpoints
for (int32 i = 0; i < fDescriptor.num_endpoints; i++)
delete fEndpoints[i];
delete fEndpoints;
}
fEndpoints = new BUSBEndpoint *[fDescriptor.num_endpoints];
fEndpoints = new(std::nothrow) BUSBEndpoint *[fDescriptor.num_endpoints];
if (fEndpoints == NULL)
return;
for (int32 i = 0; i < fDescriptor.num_endpoints; i++)
fEndpoints[i] = new BUSBEndpoint(this, i, fRawFD);
fEndpoints[i] = new(std::nothrow) BUSBEndpoint(this, i, fRawFD);
}
+31 -18
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2007, Haiku Inc. All rights reserved.
* Copyright 2007-2008, Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
@@ -16,6 +16,7 @@
#include <Path.h>
#include <stdio.h>
#include <string.h>
#include <new>
class WatchedEntry {
@@ -28,15 +29,15 @@ public:
bool EntryRemoved(ino_t node);
private:
BUSBRoster *fRoster;
BMessenger *fMessenger;
BUSBRoster * fRoster;
BMessenger * fMessenger;
node_ref fNode;
bool fIsDirectory;
BUSBDevice *fDevice;
BUSBDevice * fDevice;
WatchedEntry *fEntries;
WatchedEntry *fLink;
WatchedEntry * fEntries;
WatchedEntry * fLink;
};
@@ -49,9 +50,9 @@ public:
virtual void MessageReceived(BMessage *message);
private:
BUSBRoster *fRoster;
WatchedEntry *fRoot;
BMessenger *fMessenger;
BUSBRoster * fRoster;
WatchedEntry * fRoot;
BMessenger * fMessenger;
};
@@ -75,7 +76,11 @@ WatchedEntry::WatchedEntry(BUSBRoster *roster, BMessenger *messenger,
if (entry.GetRef(ref) < B_OK)
continue;
WatchedEntry *child = new WatchedEntry(fRoster, fMessenger, ref);
WatchedEntry *child = new(std::nothrow) WatchedEntry(fRoster,
fMessenger, ref);
if (child == NULL)
continue;
child->fLink = fEntries;
fEntries = child;
}
@@ -88,10 +93,12 @@ WatchedEntry::WatchedEntry(BUSBRoster *roster, BMessenger *messenger,
BPath path;
entry.GetPath(&path);
fDevice = new BUSBDevice(path.Path());
if (fRoster->DeviceAdded(fDevice) != B_OK) {
delete fDevice;
fDevice = NULL;
fDevice = new(std::nothrow) BUSBDevice(path.Path());
if (fDevice != NULL) {
if (fRoster->DeviceAdded(fDevice) != B_OK) {
delete fDevice;
fDevice = NULL;
}
}
}
}
@@ -132,7 +139,11 @@ WatchedEntry::EntryCreated(entry_ref *ref)
return false;
}
WatchedEntry *child = new WatchedEntry(fRoster, fMessenger, ref);
WatchedEntry *child = new(std::nothrow) WatchedEntry(fRoster, fMessenger,
ref);
if (child == NULL)
return false;
child->fLink = fEntries;
fEntries = child;
return true;
@@ -181,12 +192,14 @@ RosterLooper::RosterLooper(BUSBRoster *roster)
}
Run();
fMessenger = new BMessenger(this);
fMessenger = new(std::nothrow) BMessenger(this);
if (fMessenger == NULL)
return;
if (Lock()) {
entry_ref ref;
entry.GetRef(&ref);
fRoot = new WatchedEntry(fRoster, fMessenger, &ref);
fRoot = new(std::nothrow) WatchedEntry(fRoster, fMessenger, &ref);
Unlock();
}
}
@@ -253,7 +266,7 @@ BUSBRoster::Start()
if (fLooper)
return;
fLooper = new RosterLooper(this);
fLooper = new(std::nothrow) RosterLooper(this);
}