DF-5553 / fix.diff
fix.diff — DF-5553 (authored AFTER verification; validated at table level by table_check_fixed; NEVER applied to the read-only sys/ tree). Root cause: usb_make_raw_desc() discriminates CDC union / CDC call-management descriptors ONLY by (bLength >= 5, bDescriptorType == UDESC_CS_INTERFACE(0x24), bDescriptorSubtype == {6,1}). USB Audio class-specific descriptors share the 0x24 type byte and collide with those subtypes: AS_GENERAL is subtype 0x01 and audio feature units are subtype 0x06. The phone template therefore has five descriptors misclassified; two of them sit in non-zero-numbered interfaces and get their byte[4] incremented by the interface number (bDelay 1->2 in interface 1, 1->3 in interface 2) inside the generated configuration buffer. Fix: thread the containing interface's bInterfaceClass into the patcher and only perform CDC union / CM renumbering inside CDC (0x02) / CDC-data (0x0a) interfaces. IAD renumbering stays ungated (type 0x0B cannot collide with 0x24 and composite templates need it). Audio templates (class 0x01 interfaces) are then left byte-exact. --- a/sys/bus/u4b/template/usb_template.c +++ b/sys/bus/u4b/template/usb_template.c @@ -78,11 +78,13 @@ static void usb_make_raw_desc(struct usb_temp_setup *, const uint8_t *); static void usb_make_endpoint_desc(struct usb_temp_setup *, const struct usb_temp_endpoint_desc *); @@ -static void usb_make_raw_desc(struct usb_temp_setup *, const uint8_t *); +static void usb_make_raw_desc(struct usb_temp_setup *, const uint8_t *, + uint8_t); static void usb_make_endpoint_desc(struct usb_temp_setup *, - const struct usb_temp_endpoint_desc *); + const struct usb_temp_endpoint_desc *, uint8_t); @@ -117,8 +119,8 @@ static void -usb_make_raw_desc(struct usb_temp_setup *temp, - const uint8_t *raw) +usb_make_raw_desc(struct usb_temp_setup *temp, + const uint8_t *raw, uint8_t iface_class) { void *dst; uint8_t len; @@ -133,6 +135,10 @@ memcpy(dst, raw, len); /* check if we have got a CDC union descriptor */ + /* CDC descriptors only exist inside CDC class + * interfaces: audio CS_INTERFACE descriptors + * collide with subtypes 1 and 6 (DF-5553) */ + if ((iface_class == UICLASS_CDC) || + (iface_class == UICLASS_CDC_DATA)) { if ((raw[0] >= sizeof(struct usb_cdc_union_descriptor)) && (raw[1] == UDESC_CS_INTERFACE) && (raw[2] == UDESCSUB_CDC_UNION)) { @@ -160,6 +166,7 @@ ccd->bDataInterface += temp->bInterfaceNumber; } + } } temp->size += len; } @@ -184,8 +191,8 @@ static void usb_make_endpoint_desc(struct usb_temp_setup *temp, - const struct usb_temp_endpoint_desc *ted) + const struct usb_temp_endpoint_desc *ted, uint8_t iface_class) { @@ -211,7 +218,7 @@ rd = ted->ppRawDesc; if (rd) { while (*rd) { - usb_make_raw_desc(temp, *rd); + usb_make_raw_desc(temp, *rd, iface_class); rd++; } } @@ -319,7 +326,7 @@ if (rd) { while (*rd) { - usb_make_raw_desc(temp, *rd); + usb_make_raw_desc(temp, *rd, tid->bInterfaceClass); rd++; } } @@ -332,7 +339,7 @@ if (ted) { while (*ted) { - usb_make_endpoint_desc(temp, *ted); + usb_make_endpoint_desc(temp, *ted, + tid->bInterfaceClass); ted++; } } |