Beispiel #1
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 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;
}
Beispiel #2
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;
}