diff --git a/src/add-ons/kernel/drivers/network/ether/usb_rndis/Driver.cpp b/src/add-ons/kernel/drivers/network/ether/usb_rndis/Driver.cpp index da7bbf1d..cc5f4e1c 100644 --- a/src/add-ons/kernel/drivers/network/ether/usb_rndis/Driver.cpp +++ b/src/add-ons/kernel/drivers/network/ether/usb_rndis/Driver.cpp @@ -122,13 +122,16 @@ init_driver() &usb_rndis_device_removed }; - static usb_support_descriptor supportDescriptor = { - 0xE0, /* CDC - Wireless device */ - 0x01, 0x03, /* RNDIS subclass/protocol */ - 0, 0 /* no specific vendor or device */ + static usb_support_descriptor supportDescriptor[] = { + { // Standard USB-RNDIS devices + 0xE0, /* CDC - Wireless device */ + 0x01, 0x03, /* RNDIS subclass/protocol */ + 0, 0 /* no specific vendor or device */ + }, + { 0x02, 0x00, 0x00, 0x04e8, 0x6864 } }; - gUSBModule->register_driver(DRIVER_NAME, &supportDescriptor, 1, NULL); + gUSBModule->register_driver(DRIVER_NAME, supportDescriptor, 2, NULL); gUSBModule->install_notify(DRIVER_NAME, ¬ifyHooks); return B_OK; } diff --git a/src/add-ons/kernel/drivers/network/ether/usb_rndis/Driver.h b/src/add-ons/kernel/drivers/network/ether/usb_rndis/Driver.h index bc68cfc8..5e24174b 100644 --- a/src/add-ons/kernel/drivers/network/ether/usb_rndis/Driver.h +++ b/src/add-ons/kernel/drivers/network/ether/usb_rndis/Driver.h @@ -30,6 +30,7 @@ const char **publish_devices(); device_hooks *find_device(const char *name); } +#define TRACE_RNDIS 1 #if TRACE_RNDIS #define TRACE(x...) dprintf(DRIVER_NAME ": " x) #else diff --git a/src/add-ons/kernel/drivers/network/ether/usb_rndis/RNDISDevice.cpp b/src/add-ons/kernel/drivers/network/ether/usb_rndis/RNDISDevice.cpp index b132b28d..ee6332ed 100644 --- a/src/add-ons/kernel/drivers/network/ether/usb_rndis/RNDISDevice.cpp +++ b/src/add-ons/kernel/drivers/network/ether/usb_rndis/RNDISDevice.cpp @@ -204,7 +204,7 @@ RNDISDevice::Open() TRACE_ALWAYS("failed to read media state\n"); } - status = _ReadLinkSpeed(fDevice); + status = -1; //_ReadLinkSpeed(fDevice); if (status != B_OK) { fDownstreamSpeed = 1000 * 100; // 10Mbps TRACE_ALWAYS("failed to read link speed\n"); @@ -627,10 +627,20 @@ RNDISDevice::_SetupDevice() for (size_t j = 0; j < config->interface_count && !found; j++) { const usb_interface_info *interface = config->interface[j].active; usb_interface_descriptor *descriptor = interface->descr; - if (descriptor->interface_class != USB_COMMUNICATION_WIRELESS_DEVICE_CLASS - || descriptor->interface_subclass != 0x01 - || descriptor->interface_protocol != 0x03 - || interface->generic_count == 0) { + if (interface->generic_count == 0) { + // Ignore this interface, it doesn't have enough endpoints, try the next one + continue; + } else if (descriptor->interface_class == USB_COMMUNICATION_WIRELESS_DEVICE_CLASS + && descriptor->interface_subclass == 0x01 + && descriptor->interface_protocol == 0x03) { + // Looks good! + } else if (descriptor->interface_class == USB_COMMUNICATION_DEVICE_CLASS + && descriptor->interface_subclass == 0x02 + && descriptor->interface_protocol == 0xFF) { + // ToDo: check interface string here, "continue" if it's not "RNDIS Communications Control" + } else { + // Interface does not match either of our known ways to identify an RNDIS interface, + // ignore it and try the next one continue; } @@ -679,11 +689,25 @@ RNDISDevice::_SetupDevice() // check that the indicated control interface fits our needs usb_interface_info *interface = config->interface[controlIndex].active; usb_interface_descriptor *descriptor = interface->descr; - if ((descriptor->interface_class != 0xE0 - || descriptor->interface_subclass != 0x01 - || descriptor->interface_protocol != 0x03) - || interface->endpoint_count == 0) { - TRACE_ALWAYS("control interface invalid\n"); + + if (interface->endpoint_count == 0) { + TRACE_ALWAYS("control interface has no endpoints\n"); + return B_ERROR; + } + + if (descriptor->interface_class == USB_COMMUNICATION_WIRELESS_DEVICE_CLASS) { + if (descriptor->interface_subclass != 0x01 || descriptor->interface_protocol != 0x03) { + TRACE_ALWAYS("control interface invalid interface subclass or protocol\n"); + return B_ERROR; + } + } else if (descriptor->interface_class == USB_COMMUNICATION_DEVICE_CLASS) { + // Microsoft USBRNDIS style control interface + if (descriptor->interface_subclass != 0x02 || descriptor->interface_protocol != 0xFF) { + TRACE_ALWAYS("control interface invalid interface subclass or protocol\n"); + return B_ERROR; + } + } else { + TRACE_ALWAYS("control interface invalid interface class\n"); return B_ERROR; }