Move USB CDC Ethernet descriptor to shared header

Use the same structure in usb_ecm and listusb

Change-Id: I8d33b434560bb18bb2f6247090d1580c267adab2
Reviewed-on: https://review.haiku-os.org/c/haiku/+/11046
Tested-by: Commit checker robot <[email protected]>
Reviewed-by: waddlesplash <[email protected]>
This commit is contained in:
PulkoMandy
2026-06-01 08:00:34 +00:00
committed by Adrien Destugues
parent 30cb44085c
commit 96037d5af2
5 changed files with 66 additions and 66 deletions
+13 -2
View File
@@ -16,7 +16,7 @@ enum { // Communication Interface Subclasses
USB_CDC_COMMUNICATION_INTERFACE_TCM_SUBCLASS, // Telephone Control Model
USB_CDC_COMMUNICATION_INTERFACE_MCCM_SUBCLASS, // Multi-Channel Control Model
USB_CDC_COMMUNICATION_INTERFACE_CAPICM_SUBCLASS, // CAPI Control Model
USB_CDC_COMMUNICATION_INTERFACE_ENCM_SUBCLASS, // Ethernet Networking Control Model
USB_CDC_COMMUNICATION_INTERFACE_ECM_SUBCLASS, // Ethernet Control Model
USB_CDC_COMMUNICATION_INTERFACE_ATMNCM_SUBCLASS // ATM Networking Control Model
};
@@ -35,7 +35,8 @@ enum { // Functional Descriptors Subtypes
USB_CDC_HEADER_FUNCTIONAL_DESCRIPTOR = 0x00,
USB_CDC_CM_FUNCTIONAL_DESCRIPTOR,
USB_CDC_ACM_FUNCTIONAL_DESCRIPTOR,
USB_CDC_UNION_FUNCTIONAL_DESCRIPTOR = 0x06
USB_CDC_UNION_FUNCTIONAL_DESCRIPTOR = 0x06,
USB_CDC_ETHERNET_FUNCTIONAL_DESCRIPTOR = 0x0f
};
typedef struct usb_cdc_header_function_descriptor {
@@ -80,6 +81,16 @@ typedef struct usb_cdc_union_functional_descriptor {
uint8 slave_interfaces[1];
} _PACKED usb_cdc_union_functional_descriptor;
typedef struct usb_cdc_ethernet_functional_descriptor {
uint8 length;
uint8 descriptor_type;
uint8 descriptor_subtype; // USB_CDC_ETHERNET_FUNCTIONAL_DESCRIPTOR
uint8 mac_address_index;
uint32 ethernet_statistics;
uint16 max_segment_size;
uint16 num_multi_cast_filters;
uint8 num_wakeup_pattern_filters;
} _PACKED usb_cdc_ethernet_functional_descriptor;
enum { // Management Element Requests (p62)
USB_CDC_SEND_ENCAPSULATED_COMMAND = 0x00,
@@ -166,13 +166,15 @@ usb_ecm_supports_device(device_node *parent)
if (!strcmp(attr->name, USB_DEVICE_SUBCLASS))
subclass = attr->value.ui8;
if (baseClass != 0 && subclass != 0) {
if (baseClass == USB_INTERFACE_CLASS_CDC && subclass == USB_INTERFACE_SUBCLASS_ECM)
if (baseClass == USB_COMMUNICATION_DEVICE_CLASS
&& subclass == USB_CDC_COMMUNICATION_INTERFACE_ECM_SUBCLASS)
break;
baseClass = subclass = 0;
}
}
if (baseClass != USB_INTERFACE_CLASS_CDC || subclass != USB_INTERFACE_SUBCLASS_ECM)
if (baseClass != USB_CDC_COMMUNICATION_INTERFACE_CLASS
|| subclass != USB_CDC_COMMUNICATION_INTERFACE_ECM_SUBCLASS)
return 0.0;
TRACE("USB-ECM device found!\n");
@@ -11,6 +11,7 @@
#include <KernelExport.h>
#include <OS.h>
#include <USB3.h>
#include <usb/USB_cdc.h>
#include <util/kernel_cpp.h>
@@ -18,24 +19,8 @@
#define MAX_DEVICES 8
/* class and subclass codes */
#define USB_INTERFACE_CLASS_CDC 0x02
#define USB_INTERFACE_SUBCLASS_ECM 0x06
#define USB_INTERFACE_CLASS_CDC_DATA 0x0a
#define USB_INTERFACE_SUBCLASS_DATA 0x00
/* communication device descriptor subtypes */
#define FUNCTIONAL_SUBTYPE_UNION 0x06
#define FUNCTIONAL_SUBTYPE_ETHERNET 0x0f
typedef struct ethernet_functional_descriptor_s {
uint8 functional_descriptor_subtype;
uint8 mac_address_index;
uint32 ethernet_statistics;
uint16 max_segment_size;
uint16 num_multi_cast_filters;
uint8 num_wakeup_pattern_filters;
} _PACKED ethernet_functional_descriptor;
/* notification definitions */
#define CDC_NOTIFY_NETWORK_CONNECTION 0x00
#define CDC_NOTIFY_CONNECTION_SPEED_CHANGE 0x2a
@@ -303,7 +303,7 @@ ECMDevice::Removed()
// the notify hook is different from the read and write hooks as it does
// itself schedule traffic (while the other hooks only release a semaphore
// to notify another thread which in turn safly checks for the removed
// to notify another thread which in turn safely checks for the removed
// case) - so we must ensure that we are not inside the notify hook anymore
// before returning, as we would otherwise violate the promise not to use
// any of the pipes after returning from the removed hook
@@ -397,8 +397,8 @@ ECMDevice::_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_INTERFACE_CLASS_CDC
|| descriptor->interface_subclass != USB_INTERFACE_SUBCLASS_ECM
if (descriptor->interface_class != USB_CDC_COMMUNICATION_INTERFACE_CLASS
|| descriptor->interface_subclass != USB_CDC_COMMUNICATION_INTERFACE_ECM_SUBCLASS
|| interface->generic_count == 0) {
continue;
}
@@ -409,14 +409,14 @@ ECMDevice::_SetupDevice()
for (size_t k = 0; k < interface->generic_count; k++) {
usb_generic_descriptor *generic = &interface->generic[k]->generic;
if (generic->length >= 5
&& generic->data[0] == FUNCTIONAL_SUBTYPE_UNION) {
&& generic->data[0] == USB_CDC_UNION_FUNCTIONAL_DESCRIPTOR) {
controlIndex = generic->data[1];
dataIndex = generic->data[2];
foundUnionDescriptor = true;
} else if (generic->length >= sizeof(ethernet_functional_descriptor)
&& generic->data[0] == FUNCTIONAL_SUBTYPE_ETHERNET) {
ethernet_functional_descriptor *ethernet
= (ethernet_functional_descriptor *)generic->data;
} else if (generic->length >= sizeof(usb_cdc_ethernet_functional_descriptor)
&& generic->data[0] == USB_CDC_ETHERNET_FUNCTIONAL_DESCRIPTOR) {
usb_cdc_ethernet_functional_descriptor *ethernet
= (usb_cdc_ethernet_functional_descriptor *)generic;
fMACAddressIndex = ethernet->mac_address_index;
fMaxSegmentSize = ethernet->max_segment_size;
foundEthernetDescriptor = true;
@@ -450,8 +450,8 @@ ECMDevice::_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 != USB_INTERFACE_CLASS_CDC
|| descriptor->interface_subclass != USB_INTERFACE_SUBCLASS_ECM)
if ((descriptor->interface_class != USB_COMMUNICATION_DEVICE_CLASS
|| descriptor->interface_subclass != USB_CDC_COMMUNICATION_INTERFACE_ECM_SUBCLASS)
|| interface->endpoint_count == 0) {
TRACE_ALWAYS("control interface invalid\n");
return B_ERROR;
@@ -475,7 +475,7 @@ ECMDevice::_SetupDevice()
// alternate 0 is the disabled, endpoint-less default interface
interface = &config->interface[dataIndex].alt[1];
descriptor = interface->descr;
if (descriptor->interface_class != USB_INTERFACE_CLASS_CDC_DATA
if (descriptor->interface_class != USB_CDC_DATA_INTERFACE_CLASS
|| interface->endpoint_count < 2) {
TRACE_ALWAYS("data interface invalid\n");
return B_ERROR;
+37 -35
View File
@@ -121,180 +121,182 @@ DumpCDCDescriptor(const usb_generic_descriptor* descriptor, const BUSBInterface*
case 0x0E:
printf("CAPI control\n");
break;
case 0x0F:
case USB_CDC_ETHERNET_FUNCTIONAL_DESCRIPTOR:
{
printf("Ethernet\n");
const usb_cdc_ethernet_functional_descriptor* ethDesc
= (const usb_cdc_ethernet_functional_descriptor*)descriptor;
printf(" MAC Address ...... %s\n",
interface->Device()->DecodeStringDescriptor(descriptor->data[1]));
interface->Device()->DecodeStringDescriptor(ethDesc->mac_address_index));
printf(" Statistics ....... ");
bool somethingPrinted = false;
if ((descriptor->data[2] & 0x01) != 0) {
if ((ethDesc->ethernet_statistics & 0x01) != 0) {
printf("XMIT_OK");
somethingPrinted = true;
}
if ((descriptor->data[2] & 0x02) != 0) {
if ((ethDesc->ethernet_statistics & 0x02) != 0) {
if (somethingPrinted)
printf(", ");
printf("RCV_OK");
somethingPrinted = true;
}
if ((descriptor->data[2] & 0x04) != 0) {
if ((ethDesc->ethernet_statistics & 0x04) != 0) {
if (somethingPrinted)
printf(", ");
printf("XMIT_ERROR");
somethingPrinted = true;
}
if ((descriptor->data[2] & 0x08) != 0) {
if ((ethDesc->ethernet_statistics & 0x08) != 0) {
if (somethingPrinted)
printf(", ");
printf("RCV_ERROR");
somethingPrinted = true;
}
if ((descriptor->data[2] & 0x10) != 0) {
if ((ethDesc->ethernet_statistics & 0x10) != 0) {
if (somethingPrinted)
printf(", ");
printf("RCV_NO_BUFFER");
somethingPrinted = true;
}
if ((descriptor->data[2] & 0x20) != 0) {
if ((ethDesc->ethernet_statistics & 0x20) != 0) {
if (somethingPrinted)
printf(", ");
printf("DIRECTED_BYTES_XMIT");
somethingPrinted = true;
}
if ((descriptor->data[2] & 0x40) != 0) {
if ((ethDesc->ethernet_statistics & 0x40) != 0) {
if (somethingPrinted)
printf(", ");
printf("DIRECTED_FRAMES_XMIT");
somethingPrinted = true;
}
if ((descriptor->data[2] & 0x80) != 0) {
if ((ethDesc->ethernet_statistics & 0x80) != 0) {
if (somethingPrinted)
printf(", ");
printf("MULTICAST_BYTES_XMIT");
somethingPrinted = true;
}
if ((descriptor->data[3] & 0x01) != 0) {
if ((ethDesc->ethernet_statistics & 0x0100) != 0) {
if (somethingPrinted)
printf(", ");
printf("MULTICAST_FRAMES_XMIT");
somethingPrinted = true;
}
if ((descriptor->data[3] & 0x02) != 0) {
if ((ethDesc->ethernet_statistics & 0x0200) != 0) {
if (somethingPrinted)
printf(", ");
printf("BROADCAST_BYTES_XMIT");
somethingPrinted = true;
}
if ((descriptor->data[3] & 0x04) != 0) {
if ((ethDesc->ethernet_statistics & 0x0400) != 0) {
if (somethingPrinted)
printf(", ");
printf("BROADCAST_FRAMES_XMIT");
somethingPrinted = true;
}
if ((descriptor->data[3] & 0x08) != 0) {
if ((ethDesc->ethernet_statistics & 0x0800) != 0) {
if (somethingPrinted)
printf(", ");
printf("DIRECTED_BYTES_RCV");
somethingPrinted = true;
}
if ((descriptor->data[3] & 0x10) != 0) {
if ((ethDesc->ethernet_statistics & 0x1000) != 0) {
if (somethingPrinted)
printf(", ");
printf("DIRECTED_FRAMES_RCV");
somethingPrinted = true;
}
if ((descriptor->data[3] & 0x20) != 0) {
if ((ethDesc->ethernet_statistics & 0x2000) != 0) {
if (somethingPrinted)
printf(", ");
printf("MULTICAST_BYTES_RCV");
somethingPrinted = true;
}
if ((descriptor->data[3] & 0x40) != 0) {
if ((ethDesc->ethernet_statistics & 0x4000) != 0) {
if (somethingPrinted)
printf(", ");
printf("MULTICAST_FRAMES_RCV");
somethingPrinted = true;
}
if ((descriptor->data[3] & 0x80) != 0) {
if ((ethDesc->ethernet_statistics & 0x8000) != 0) {
if (somethingPrinted)
printf(", ");
printf("BROADCAST_BYTES_RCV");
somethingPrinted = true;
}
if ((descriptor->data[4] & 0x01) != 0) {
if ((ethDesc->ethernet_statistics & 0x010000) != 0) {
if (somethingPrinted)
printf(", ");
printf("BROADCAST_FRAMES_RCV");
somethingPrinted = true;
}
if ((descriptor->data[4] & 0x02) != 0) {
if ((ethDesc->ethernet_statistics & 0x020000) != 0) {
if (somethingPrinted)
printf(", ");
printf("RCV_CRC_ERROR");
somethingPrinted = true;
}
if ((descriptor->data[4] & 0x04) != 0) {
if ((ethDesc->ethernet_statistics & 0x040000) != 0) {
if (somethingPrinted)
printf(", ");
printf("TRANSMIT_QUEUE_LENGTH");
somethingPrinted = true;
}
if ((descriptor->data[4] & 0x08) != 0) {
if ((ethDesc->ethernet_statistics & 0x080000) != 0) {
if (somethingPrinted)
printf(", ");
printf("RCV_ERROR_ALIGNMENT");
somethingPrinted = true;
}
if ((descriptor->data[4] & 0x10) != 0) {
if ((ethDesc->ethernet_statistics & 0x100000) != 0) {
if (somethingPrinted)
printf(", ");
printf("XMIT_ONE_COLLISION");
somethingPrinted = true;
}
if ((descriptor->data[4] & 0x20) != 0) {
if ((ethDesc->ethernet_statistics & 0x200000) != 0) {
if (somethingPrinted)
printf(", ");
printf("XMIT_MORE_COLLISIONS");
somethingPrinted = true;
}
if ((descriptor->data[4] & 0x40) != 0) {
if ((ethDesc->ethernet_statistics & 0x400000) != 0) {
if (somethingPrinted)
printf(", ");
printf("XMIT_DEFERRED");
somethingPrinted = true;
}
if ((descriptor->data[4] & 0x80) != 0) {
if ((ethDesc->ethernet_statistics & 0x800000) != 0) {
if (somethingPrinted)
printf(", ");
printf("XMIT_MAX_COLLISIONS");
somethingPrinted = true;
}
if ((descriptor->data[5] & 0x01) != 0) {
if ((ethDesc->ethernet_statistics & 0x01000000) != 0) {
if (somethingPrinted)
printf(", ");
printf("RCV_OVERRUN");
somethingPrinted = true;
}
if ((descriptor->data[5] & 0x02) != 0) {
if ((ethDesc->ethernet_statistics & 0x02000000) != 0) {
if (somethingPrinted)
printf(", ");
printf("XMIT_UNDERRUN");
somethingPrinted = true;
}
if ((descriptor->data[5] & 0x04) != 0) {
if ((ethDesc->ethernet_statistics & 0x04000000) != 0) {
if (somethingPrinted)
printf(", ");
printf("XMIT_HEARTBEAT_FAILURE");
somethingPrinted = true;
}
if ((descriptor->data[5] & 0x08) != 0) {
if ((ethDesc->ethernet_statistics & 0x08000000) != 0) {
if (somethingPrinted)
printf(", ");
printf("XMIT_TIMES_CRS_LOST");
somethingPrinted = true;
}
if ((descriptor->data[5] & 0x10) != 0) {
if ((ethDesc->ethernet_statistics & 0x10000000) != 0) {
if (somethingPrinted)
printf(", ");
printf("XMIT_LATE_COLLISIONS");
@@ -305,11 +307,11 @@ DumpCDCDescriptor(const usb_generic_descriptor* descriptor, const BUSBInterface*
printf("None");
printf("\n");
printf(" Max. Segment Size %d\n",
descriptor->data[6] | descriptor->data[7] << 8);
ethDesc->max_segment_size);
printf(" Multicast filters %d\n",
descriptor->data[8] | descriptor->data[9] << 8);
printf(" Power filters ... %d\n",
descriptor->data[10]);
ethDesc->num_multi_cast_filters);
printf(" Wakeup filters .. %d\n",
ethDesc->num_wakeup_pattern_filters);
return;
}
case 0x10: