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