LCOV - code coverage report
Current view: top level - drivers/gpu/drm - drm_displayid.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 50 0.0 %
Date: 2022-12-09 01:23:36 Functions: 0 5 0.0 %

          Line data    Source code
       1             : // SPDX-License-Identifier: MIT
       2             : /*
       3             :  * Copyright © 2021 Intel Corporation
       4             :  */
       5             : 
       6             : #include <drm/drm_displayid.h>
       7             : #include <drm/drm_edid.h>
       8             : #include <drm/drm_print.h>
       9             : 
      10           0 : static int validate_displayid(const u8 *displayid, int length, int idx)
      11             : {
      12             :         int i, dispid_length;
      13           0 :         u8 csum = 0;
      14             :         const struct displayid_header *base;
      15             : 
      16           0 :         base = (const struct displayid_header *)&displayid[idx];
      17             : 
      18           0 :         DRM_DEBUG_KMS("base revision 0x%x, length %d, %d %d\n",
      19             :                       base->rev, base->bytes, base->prod_id, base->ext_count);
      20             : 
      21             :         /* +1 for DispID checksum */
      22           0 :         dispid_length = sizeof(*base) + base->bytes + 1;
      23           0 :         if (dispid_length > length - idx)
      24             :                 return -EINVAL;
      25             : 
      26           0 :         for (i = 0; i < dispid_length; i++)
      27           0 :                 csum += displayid[idx + i];
      28           0 :         if (csum) {
      29           0 :                 DRM_NOTE("DisplayID checksum invalid, remainder is %d\n", csum);
      30           0 :                 return -EINVAL;
      31             :         }
      32             : 
      33             :         return 0;
      34             : }
      35             : 
      36           0 : static const u8 *drm_find_displayid_extension(const struct edid *edid,
      37             :                                               int *length, int *idx,
      38             :                                               int *ext_index)
      39             : {
      40           0 :         const u8 *displayid = drm_find_edid_extension(edid, DISPLAYID_EXT, ext_index);
      41             :         const struct displayid_header *base;
      42             :         int ret;
      43             : 
      44           0 :         if (!displayid)
      45             :                 return NULL;
      46             : 
      47             :         /* EDID extensions block checksum isn't for us */
      48           0 :         *length = EDID_LENGTH - 1;
      49           0 :         *idx = 1;
      50             : 
      51           0 :         ret = validate_displayid(displayid, *length, *idx);
      52           0 :         if (ret)
      53             :                 return NULL;
      54             : 
      55           0 :         base = (const struct displayid_header *)&displayid[*idx];
      56           0 :         *length = *idx + sizeof(*base) + base->bytes;
      57             : 
      58           0 :         return displayid;
      59             : }
      60             : 
      61           0 : void displayid_iter_edid_begin(const struct edid *edid,
      62             :                                struct displayid_iter *iter)
      63             : {
      64           0 :         memset(iter, 0, sizeof(*iter));
      65             : 
      66           0 :         iter->edid = edid;
      67           0 : }
      68             : 
      69             : static const struct displayid_block *
      70             : displayid_iter_block(const struct displayid_iter *iter)
      71             : {
      72             :         const struct displayid_block *block;
      73             : 
      74           0 :         if (!iter->section)
      75             :                 return NULL;
      76             : 
      77           0 :         block = (const struct displayid_block *)&iter->section[iter->idx];
      78             : 
      79           0 :         if (iter->idx + sizeof(*block) <= iter->length &&
      80           0 :             iter->idx + sizeof(*block) + block->num_bytes <= iter->length)
      81             :                 return block;
      82             : 
      83             :         return NULL;
      84             : }
      85             : 
      86             : const struct displayid_block *
      87           0 : __displayid_iter_next(struct displayid_iter *iter)
      88             : {
      89             :         const struct displayid_block *block;
      90             : 
      91           0 :         if (!iter->edid)
      92             :                 return NULL;
      93             : 
      94           0 :         if (iter->section) {
      95             :                 /* current block should always be valid */
      96           0 :                 block = displayid_iter_block(iter);
      97           0 :                 if (WARN_ON(!block)) {
      98           0 :                         iter->section = NULL;
      99           0 :                         iter->edid = NULL;
     100           0 :                         return NULL;
     101             :                 }
     102             : 
     103             :                 /* next block in section */
     104           0 :                 iter->idx += sizeof(*block) + block->num_bytes;
     105             : 
     106           0 :                 block = displayid_iter_block(iter);
     107           0 :                 if (block)
     108             :                         return block;
     109             :         }
     110             : 
     111             :         for (;;) {
     112           0 :                 iter->section = drm_find_displayid_extension(iter->edid,
     113             :                                                              &iter->length,
     114             :                                                              &iter->idx,
     115             :                                                              &iter->ext_index);
     116           0 :                 if (!iter->section) {
     117           0 :                         iter->edid = NULL;
     118           0 :                         return NULL;
     119             :                 }
     120             : 
     121           0 :                 iter->idx += sizeof(struct displayid_header);
     122             : 
     123           0 :                 block = displayid_iter_block(iter);
     124           0 :                 if (block)
     125             :                         return block;
     126             :         }
     127             : }
     128             : 
     129           0 : void displayid_iter_end(struct displayid_iter *iter)
     130             : {
     131           0 :         memset(iter, 0, sizeof(*iter));
     132           0 : }

Generated by: LCOV version 1.14