* 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:
+60
-48
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user