/* * Sanity check the EDID block (base or extension). Return 0 if the block * doesn't check out, or 1 if it's valid. */ bool drm_edid_block_valid(u8 *raw_edid) { int i; u8 csum = 0; struct edid *edid = (struct edid *)raw_edid; if (raw_edid[0] == 0x00) { int score = drm_edid_header_is_valid(raw_edid); if (score == 8) ; else if (score >= 6) { fprintf(stderr, "[000000.0] [drm:%s], ", __func__); fprintf(stderr, "Fixing EDID header, your hardware may be failing\n"); memcpy(raw_edid, edid_header, sizeof(edid_header)); } else { goto bad; } } for (i = 0; i < EDID_LENGTH; i++) csum += raw_edid[i]; if (csum) { fprintf(stderr, "[000000.0] [drm:%s], ", __func__); fprintf(stderr, "EDID checksum is invalid, remainder is %d\n", csum); /* allow CEA to slide through, switches mangle this */ if (raw_edid[0] != 0x02) goto bad; } /* per-block-type checks */ switch (raw_edid[0]) { case 0: /* base */ if (edid->version != 1) { fprintf(stderr, "[000000.0] [drm:%s], ", __func__); fprintf(stderr, "EDID has major version %d, instead of 1\n", edid->version); goto bad; } if (edid->revision > 4) { fprintf(stderr, "[000000.0] [drm:%s], ", __func__); fprintf(stderr, "EDID minor > 4, assuming backward compatibility\n"); } break; default: break; } return 1; bad: if (raw_edid) { fprintf(stderr, "[000000.0] [drm:%s], ", __func__); fprintf(stderr, KERN_ERR "Raw EDID:\n"); print_hex_dump(KERN_ERR, " \t", DUMP_PREFIX_NONE, 16, 1, raw_edid, EDID_LENGTH, false); } return 0; }
/* * Sanity check the EDID block (base or extension). Return 0 if the block * doesn't check out, or 1 if it's valid. */ bool drm_edid_block_valid(u8 *raw_edid, int block, bool print_bad_edid) { int i; u8 csum = 0; struct edid *edid = (struct edid *)raw_edid; if (edid_fixup > 8 || edid_fixup < 0) edid_fixup = 6; if (block == 0) { int score = drm_edid_header_is_valid(raw_edid); if (score == 8) ; else if (score >= edid_fixup) { DRM_DEBUG("Fixing EDID header, your hardware may be failing\n"); memcpy(raw_edid, edid_header, sizeof(edid_header)); } else { goto bad; } } for (i = 0; i < EDID_LENGTH; i++) csum += raw_edid[i]; if (csum) { if (print_bad_edid) { DRM_ERROR("EDID checksum is invalid, remainder is %d\n", csum); } /* allow CEA to slide through, switches mangle this */ if (raw_edid[0] != 0x02) goto bad; } /* per-block-type checks */ switch (raw_edid[0]) { case 0: /* base */ if (edid->version != 1) { DRM_ERROR("EDID has major version %d, instead of 1\n", edid->version); goto bad; } if (edid->revision > 4) DRM_DEBUG("EDID minor > 4, assuming backward compatibility\n"); break; default: break; } return 1; bad: if (raw_edid && print_bad_edid) { DRM_DEBUG_KMS("Raw EDID:\n"); if ((drm_debug & DRM_DEBUGBITS_KMS) != 0) { for (i = 0; i < EDID_LENGTH; ) { kprintf("%02x", raw_edid[i]); i++; if (i % 16 == 0 || i == EDID_LENGTH) kprintf("\n"); else if (i % 8 == 0) kprintf(" "); else kprintf(" "); } } } return 0; }