From 89dda2805209631fb64bd73e4f30df28405ca985 Mon Sep 17 00:00:00 2001 From: Michael Lotz Date: Wed, 10 Sep 2008 21:52:32 +0000 Subject: [PATCH] * 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 --- headers/os/device/USBKit.h | 108 +++--- .../kernel/drivers/bus/usb/usb_raw.cpp | 310 ++++++++++-------- src/add-ons/kernel/drivers/bus/usb/usb_raw.h | 43 ++- src/kits/device/USBConfiguration.cpp | 34 +- src/kits/device/USBDevice.cpp | 55 ++-- src/kits/device/USBEndpoint.cpp | 31 +- src/kits/device/USBInterface.cpp | 124 ++++--- src/kits/device/USBRoster.cpp | 49 ++- 8 files changed, 455 insertions(+), 299 deletions(-) diff --git a/headers/os/device/USBKit.h b/headers/os/device/USBKit.h index 07189e66fd..e6b047de91 100644 --- a/headers/os/device/USBKit.h +++ b/headers/os/device/USBKit.h @@ -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; diff --git a/src/add-ons/kernel/drivers/bus/usb/usb_raw.cpp b/src/add-ons/kernel/drivers/bus/usb/usb_raw.cpp index 35b976590d..083c38333d 100644 --- a/src/add-ons/kernel/drivers/bus/usb/usb_raw.cpp +++ b/src/add-ons/kernel/drivers/bus/usb/usb_raw.cpp @@ -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; } diff --git a/src/add-ons/kernel/drivers/bus/usb/usb_raw.h b/src/add-ons/kernel/drivers/bus/usb/usb_raw.h index 9b00e8169c..54112c2202 100644 --- a/src/add-ons/kernel/drivers/bus/usb/usb_raw.h +++ b/src/add-ons/kernel/drivers/bus/usb/usb_raw.h @@ -9,6 +9,7 @@ #include #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; diff --git a/src/kits/device/USBConfiguration.cpp b/src/kits/device/USBConfiguration.cpp index 831f824b86..cf158a06e2 100644 --- a/src/kits/device/USBConfiguration.cpp +++ b/src/kits/device/USBConfiguration.cpp @@ -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 #include #include +#include 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]; diff --git a/src/kits/device/USBDevice.cpp b/src/kits/device/USBDevice.cpp index 9eab50e5a2..d7c222da13 100644 --- a/src/kits/device/USBDevice.cpp +++ b/src/kits/device/USBDevice.cpp @@ -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 #include +#include #include #include -#include +#include 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]; } diff --git a/src/kits/device/USBEndpoint.cpp b/src/kits/device/USBEndpoint.cpp index 8a128d1621..11cda95ea2 100644 --- a/src/kits/device/USBEndpoint.cpp +++ b/src/kits/device/USBEndpoint.cpp @@ -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; } diff --git a/src/kits/device/USBInterface.cpp b/src/kits/device/USBInterface.cpp index d4f8da7594..a242466878 100644 --- a/src/kits/device/USBInterface.cpp +++ b/src/kits/device/USBInterface.cpp @@ -15,11 +15,15 @@ #include -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); } diff --git a/src/kits/device/USBRoster.cpp b/src/kits/device/USBRoster.cpp index e0f2f2eb6c..e176220607 100644 --- a/src/kits/device/USBRoster.cpp +++ b/src/kits/device/USBRoster.cpp @@ -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 #include #include +#include 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); }