DF-5555 / fix.diff
fix.diff — DF-5555 (authored AFTER verification; validated at table level by table_check_fixed; NEVER applied to the read-only sys/ tree). Identical core change as DF-5553's fix.diff — the audio template is the second member of the family the class gate closes ("closes the whole family", DF-5553 verdict). 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 (bDelay at byte[4]) and audio feature units are subtype 0x06 (bUnitID/bSourceID at bytes [3]/[4]). On the audio template the heuristic fires on 9 descriptors: audio_raw_desc_20 (iface 1) gets bDelay 0x03->0x04, audio_raw_desc_30 (iface 2) gets bDelay 0x01->0x03, and the seven interface-0 hits (AC header + six feature units) sit at zero delta only because the AudioControl interface is number 0. 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/DF-5555) */ + 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++; } } |