jcs's openbsd hax
openbsd

drm/displayid: add quirk to ignore DisplayID checksum errors

From Jani Nikula
f548c5ebe656506e81a8145798ff194d57d00a3c in linux-6.12.y/6.12.64
83cbb4d33dc22b0ca1a4e85c6e892c9b729e28d4 in mainline linux

jsg bbdb2fea a723cdf1

+39 -4
+37 -4
sys/dev/pci/drm/drm_displayid.c
··· 9 9 #include "drm_crtc_internal.h" 10 10 #include "drm_displayid_internal.h" 11 11 12 + enum { 13 + QUIRK_IGNORE_CHECKSUM, 14 + }; 15 + 16 + struct displayid_quirk { 17 + const struct drm_edid_ident ident; 18 + u8 quirks; 19 + }; 20 + 21 + static const struct displayid_quirk quirks[] = { 22 + { 23 + .ident = DRM_EDID_IDENT_INIT('C', 'S', 'O', 5142, "MNE007ZA1-5"), 24 + .quirks = BIT(QUIRK_IGNORE_CHECKSUM), 25 + }, 26 + }; 27 + 28 + static u8 get_quirks(const struct drm_edid *drm_edid) 29 + { 30 + int i; 31 + 32 + for (i = 0; i < ARRAY_SIZE(quirks); i++) { 33 + if (drm_edid_match(drm_edid, &quirks[i].ident)) 34 + return quirks[i].quirks; 35 + } 36 + 37 + return 0; 38 + } 39 + 12 40 static const struct displayid_header * 13 41 displayid_get_header(const u8 *displayid, int length, int index) 14 42 { ··· 23 51 } 24 52 25 53 static const struct displayid_header * 26 - validate_displayid(const u8 *displayid, int length, int idx) 54 + validate_displayid(const u8 *displayid, int length, int idx, bool ignore_checksum) 27 55 { 28 56 int i, dispid_length; 29 57 u8 csum = 0; ··· 41 69 for (i = 0; i < dispid_length; i++) 42 70 csum += displayid[idx + i]; 43 71 if (csum) { 44 - DRM_NOTE("DisplayID checksum invalid, remainder is %d\n", csum); 45 - return ERR_PTR(-EINVAL); 72 + DRM_NOTE("DisplayID checksum invalid, remainder is %d%s\n", csum, 73 + ignore_checksum ? " (ignoring)" : ""); 74 + 75 + if (!ignore_checksum) 76 + return ERR_PTR(-EINVAL); 46 77 } 47 78 48 79 return base; ··· 52 83 { 53 84 const struct displayid_header *base; 54 85 const u8 *displayid; 86 + bool ignore_checksum = iter->quirks & BIT(QUIRK_IGNORE_CHECKSUM); 55 87 56 88 displayid = drm_edid_find_extension(iter->drm_edid, DISPLAYID_EXT, &iter->ext_index); 57 89 if (!displayid) ··· 61 93 iter->length = EDID_LENGTH - 1; 62 94 iter->idx = 1; 63 95 64 - base = validate_displayid(displayid, iter->length, iter->idx); 96 + base = validate_displayid(displayid, iter->length, iter->idx, ignore_checksum); 65 97 if (IS_ERR(base)) 66 98 return NULL; 67 99 ··· 76 108 memset(iter, 0, sizeof(*iter)); 77 109 78 110 iter->drm_edid = drm_edid; 111 + iter->quirks = get_quirks(drm_edid); 79 112 } 80 113 81 114 static const struct displayid_block *
+2
sys/dev/pci/drm/drm_displayid_internal.h
··· 154 154 155 155 u8 version; 156 156 u8 primary_use; 157 + 158 + u8 quirks; 157 159 }; 158 160 159 161 void displayid_iter_edid_begin(const struct drm_edid *drm_edid,