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:
committed by
Adrien Destugues
parent
30cb44085c
commit
96037d5af2
@@ -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
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user