From patchwork Thu Sep 20 18:51:28 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?VmlsbGUgU3lyasOkbMOk?= X-Patchwork-Id: 10608537 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 2E87D5A4 for ; Thu, 20 Sep 2018 18:51:55 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1FC9C2E259 for ; Thu, 20 Sep 2018 18:51:55 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 142F42E300; Thu, 20 Sep 2018 18:51:55 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5E5ED2E259 for ; Thu, 20 Sep 2018 18:51:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2388161AbeIUAgo (ORCPT ); Thu, 20 Sep 2018 20:36:44 -0400 Received: from mga18.intel.com ([134.134.136.126]:4218 "EHLO mga18.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727171AbeIUAgo (ORCPT ); Thu, 20 Sep 2018 20:36:44 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga106.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 20 Sep 2018 11:51:52 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.54,281,1534834800"; d="scan'208";a="87926668" Received: from stinkbox.fi.intel.com (HELO stinkbox) ([10.237.72.174]) by fmsmga002.fm.intel.com with SMTP; 20 Sep 2018 11:51:49 -0700 Received: by stinkbox (sSMTP sendmail emulation); Thu, 20 Sep 2018 21:51:49 +0300 From: Ville Syrjala To: dri-devel@lists.freedesktop.org Cc: intel-gfx@lists.freedesktop.org, Thierry Reding , Hans Verkuil , linux-media@vger.kernel.org Subject: [PATCH 01/18] video/hdmi: Constify 'buffer' to the unpack functions Date: Thu, 20 Sep 2018 21:51:28 +0300 Message-Id: <20180920185145.1912-2-ville.syrjala@linux.intel.com> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20180920185145.1912-1-ville.syrjala@linux.intel.com> References: <20180920185145.1912-1-ville.syrjala@linux.intel.com> MIME-Version: 1.0 Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Ville Syrjälä The unpack functions just read from the passed in buffer, so make it const. Cc: Thierry Reding Cc: Hans Verkuil Cc: linux-media@vger.kernel.org Signed-off-by: Ville Syrjälä Acked-by: Hans Verkuil --- drivers/video/hdmi.c | 23 ++++++++++++----------- include/linux/hdmi.h | 3 ++- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c index 38716eb50408..65b915ea4936 100644 --- a/drivers/video/hdmi.c +++ b/drivers/video/hdmi.c @@ -31,7 +31,7 @@ #define hdmi_log(fmt, ...) dev_printk(level, dev, fmt, ##__VA_ARGS__) -static u8 hdmi_infoframe_checksum(u8 *ptr, size_t size) +static u8 hdmi_infoframe_checksum(const u8 *ptr, size_t size) { u8 csum = 0; size_t i; @@ -1016,9 +1016,9 @@ EXPORT_SYMBOL(hdmi_infoframe_log); * Returns 0 on success or a negative error code on failure. */ static int hdmi_avi_infoframe_unpack(struct hdmi_avi_infoframe *frame, - void *buffer) + const void *buffer) { - u8 *ptr = buffer; + const u8 *ptr = buffer; int ret; if (ptr[0] != HDMI_INFOFRAME_TYPE_AVI || @@ -1079,9 +1079,9 @@ static int hdmi_avi_infoframe_unpack(struct hdmi_avi_infoframe *frame, * Returns 0 on success or a negative error code on failure. */ static int hdmi_spd_infoframe_unpack(struct hdmi_spd_infoframe *frame, - void *buffer) + const void *buffer) { - u8 *ptr = buffer; + const u8 *ptr = buffer; int ret; if (ptr[0] != HDMI_INFOFRAME_TYPE_SPD || @@ -1117,9 +1117,9 @@ static int hdmi_spd_infoframe_unpack(struct hdmi_spd_infoframe *frame, * Returns 0 on success or a negative error code on failure. */ static int hdmi_audio_infoframe_unpack(struct hdmi_audio_infoframe *frame, - void *buffer) + const void *buffer) { - u8 *ptr = buffer; + const u8 *ptr = buffer; int ret; if (ptr[0] != HDMI_INFOFRAME_TYPE_AUDIO || @@ -1163,9 +1163,9 @@ static int hdmi_audio_infoframe_unpack(struct hdmi_audio_infoframe *frame, */ static int hdmi_vendor_any_infoframe_unpack(union hdmi_vendor_any_infoframe *frame, - void *buffer) + const void *buffer) { - u8 *ptr = buffer; + const u8 *ptr = buffer; size_t length; int ret; u8 hdmi_video_format; @@ -1234,10 +1234,11 @@ hdmi_vendor_any_infoframe_unpack(union hdmi_vendor_any_infoframe *frame, * * Returns 0 on success or a negative error code on failure. */ -int hdmi_infoframe_unpack(union hdmi_infoframe *frame, void *buffer) +int hdmi_infoframe_unpack(union hdmi_infoframe *frame, + const void *buffer) { int ret; - u8 *ptr = buffer; + const u8 *ptr = buffer; switch (ptr[0]) { case HDMI_INFOFRAME_TYPE_AVI: diff --git a/include/linux/hdmi.h b/include/linux/hdmi.h index d271ff23984f..d3816170c062 100644 --- a/include/linux/hdmi.h +++ b/include/linux/hdmi.h @@ -332,7 +332,8 @@ union hdmi_infoframe { ssize_t hdmi_infoframe_pack(union hdmi_infoframe *frame, void *buffer, size_t size); -int hdmi_infoframe_unpack(union hdmi_infoframe *frame, void *buffer); +int hdmi_infoframe_unpack(union hdmi_infoframe *frame, + const void *buffer); void hdmi_infoframe_log(const char *level, struct device *dev, union hdmi_infoframe *frame); From patchwork Thu Sep 20 18:51:29 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?VmlsbGUgU3lyasOkbMOk?= X-Patchwork-Id: 10608541 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 7E3A515E8 for ; Thu, 20 Sep 2018 18:51:58 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6CF042E259 for ; Thu, 20 Sep 2018 18:51:58 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 60F552E307; Thu, 20 Sep 2018 18:51:58 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8C23D2E2FE for ; Thu, 20 Sep 2018 18:51:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2388172AbeIUAgs (ORCPT ); Thu, 20 Sep 2018 20:36:48 -0400 Received: from mga03.intel.com ([134.134.136.65]:25817 "EHLO mga03.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727171AbeIUAgs (ORCPT ); Thu, 20 Sep 2018 20:36:48 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by orsmga103.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 20 Sep 2018 11:51:56 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.54,281,1534834800"; d="scan'208";a="71620266" Received: from stinkbox.fi.intel.com (HELO stinkbox) ([10.237.72.174]) by fmsmga007.fm.intel.com with SMTP; 20 Sep 2018 11:51:53 -0700 Received: by stinkbox (sSMTP sendmail emulation); Thu, 20 Sep 2018 21:51:52 +0300 From: Ville Syrjala To: dri-devel@lists.freedesktop.org Cc: intel-gfx@lists.freedesktop.org, Thierry Reding , Hans Verkuil , linux-media@vger.kernel.org Subject: [PATCH 02/18] video/hdmi: Pass buffer size to infoframe unpack functions Date: Thu, 20 Sep 2018 21:51:29 +0300 Message-Id: <20180920185145.1912-3-ville.syrjala@linux.intel.com> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20180920185145.1912-1-ville.syrjala@linux.intel.com> References: <20180920185145.1912-1-ville.syrjala@linux.intel.com> MIME-Version: 1.0 Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Ville Syrjälä To make sure the infoframe unpack functions don't end up examining stack garbage or oopsing, let's pass in the size of the buffer. v2: Convert tda1997x.c as well (kbuild test robot) Cc: Thierry Reding Cc: Hans Verkuil Cc: linux-media@vger.kernel.org Signed-off-by: Ville Syrjälä Acked-by: Hans Verkuil --- drivers/media/i2c/adv7511.c | 2 +- drivers/media/i2c/adv7604.c | 2 +- drivers/media/i2c/adv7842.c | 2 +- drivers/media/i2c/tc358743.c | 2 +- drivers/media/i2c/tda1997x.c | 4 ++-- drivers/video/hdmi.c | 51 ++++++++++++++++++++++++++++++++------------ include/linux/hdmi.h | 2 +- 7 files changed, 44 insertions(+), 21 deletions(-) diff --git a/drivers/media/i2c/adv7511.c b/drivers/media/i2c/adv7511.c index 55c2ea0720d9..b85b181bbb6c 100644 --- a/drivers/media/i2c/adv7511.c +++ b/drivers/media/i2c/adv7511.c @@ -550,7 +550,7 @@ static void log_infoframe(struct v4l2_subdev *sd, const struct adv7511_cfg_read_ buffer[3] = 0; buffer[3] = hdmi_infoframe_checksum(buffer, len + 4); - if (hdmi_infoframe_unpack(&frame, buffer) < 0) { + if (hdmi_infoframe_unpack(&frame, buffer, sizeof(buffer)) < 0) { v4l2_err(sd, "%s: unpack of %s infoframe failed\n", __func__, cri->desc); return; } diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c index 668be2bca57a..2e7a28dbad4e 100644 --- a/drivers/media/i2c/adv7604.c +++ b/drivers/media/i2c/adv7604.c @@ -2418,7 +2418,7 @@ static int adv76xx_read_infoframe(struct v4l2_subdev *sd, int index, buffer[i + 3] = infoframe_read(sd, adv76xx_cri[index].payload_addr + i); - if (hdmi_infoframe_unpack(frame, buffer) < 0) { + if (hdmi_infoframe_unpack(frame, buffer, sizeof(buffer)) < 0) { v4l2_err(sd, "%s: unpack of %s infoframe failed\n", __func__, adv76xx_cri[index].desc); return -ENOENT; diff --git a/drivers/media/i2c/adv7842.c b/drivers/media/i2c/adv7842.c index 4f8fbdd00e35..2cfd03f929b2 100644 --- a/drivers/media/i2c/adv7842.c +++ b/drivers/media/i2c/adv7842.c @@ -2563,7 +2563,7 @@ static void log_infoframe(struct v4l2_subdev *sd, struct adv7842_cfg_read_infofr for (i = 0; i < len; i++) buffer[i + 3] = infoframe_read(sd, cri->payload_addr + i); - if (hdmi_infoframe_unpack(&frame, buffer) < 0) { + if (hdmi_infoframe_unpack(&frame, buffer, sizeof(buffer)) < 0) { v4l2_err(sd, "%s: unpack of %s infoframe failed\n", __func__, cri->desc); return; } diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c index 44c41933415a..519bf92508d5 100644 --- a/drivers/media/i2c/tc358743.c +++ b/drivers/media/i2c/tc358743.c @@ -444,7 +444,7 @@ static void print_avi_infoframe(struct v4l2_subdev *sd) i2c_rd(sd, PK_AVI_0HEAD, buffer, HDMI_INFOFRAME_SIZE(AVI)); - if (hdmi_infoframe_unpack(&frame, buffer) < 0) { + if (hdmi_infoframe_unpack(&frame, buffer, sizeof(buffer)) < 0) { v4l2_err(sd, "%s: unpack of AVI infoframe failed\n", __func__); return; } diff --git a/drivers/media/i2c/tda1997x.c b/drivers/media/i2c/tda1997x.c index d114ac5243ec..195a1fc74ee8 100644 --- a/drivers/media/i2c/tda1997x.c +++ b/drivers/media/i2c/tda1997x.c @@ -1253,7 +1253,7 @@ tda1997x_parse_infoframe(struct tda1997x_state *state, u16 addr) /* read data */ len = io_readn(sd, addr, sizeof(buffer), buffer); - err = hdmi_infoframe_unpack(&frame, buffer); + err = hdmi_infoframe_unpack(&frame, buffer, sizeof(buffer)); if (err) { v4l_err(state->client, "failed parsing %d byte infoframe: 0x%04x/0x%02x\n", @@ -1928,7 +1928,7 @@ static int tda1997x_log_infoframe(struct v4l2_subdev *sd, int addr) /* read data */ len = io_readn(sd, addr, sizeof(buffer), buffer); v4l2_dbg(1, debug, sd, "infoframe: addr=%d len=%d\n", addr, len); - err = hdmi_infoframe_unpack(&frame, buffer); + err = hdmi_infoframe_unpack(&frame, buffer, sizeof(buffer)); if (err) { v4l_err(state->client, "failed parsing %d byte infoframe: 0x%04x/0x%02x\n", diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c index 65b915ea4936..b5d491014b0b 100644 --- a/drivers/video/hdmi.c +++ b/drivers/video/hdmi.c @@ -1005,8 +1005,9 @@ EXPORT_SYMBOL(hdmi_infoframe_log); /** * hdmi_avi_infoframe_unpack() - unpack binary buffer to a HDMI AVI infoframe - * @buffer: source buffer * @frame: HDMI AVI infoframe + * @buffer: source buffer + * @size: size of buffer * * Unpacks the information contained in binary @buffer into a structured * @frame of the HDMI Auxiliary Video (AVI) information frame. @@ -1016,11 +1017,14 @@ EXPORT_SYMBOL(hdmi_infoframe_log); * Returns 0 on success or a negative error code on failure. */ static int hdmi_avi_infoframe_unpack(struct hdmi_avi_infoframe *frame, - const void *buffer) + const void *buffer, size_t size) { const u8 *ptr = buffer; int ret; + if (size < HDMI_INFOFRAME_SIZE(AVI)) + return -EINVAL; + if (ptr[0] != HDMI_INFOFRAME_TYPE_AVI || ptr[1] != 2 || ptr[2] != HDMI_AVI_INFOFRAME_SIZE) @@ -1068,8 +1072,9 @@ static int hdmi_avi_infoframe_unpack(struct hdmi_avi_infoframe *frame, /** * hdmi_spd_infoframe_unpack() - unpack binary buffer to a HDMI SPD infoframe - * @buffer: source buffer * @frame: HDMI SPD infoframe + * @buffer: source buffer + * @size: size of buffer * * Unpacks the information contained in binary @buffer into a structured * @frame of the HDMI Source Product Description (SPD) information frame. @@ -1079,11 +1084,14 @@ static int hdmi_avi_infoframe_unpack(struct hdmi_avi_infoframe *frame, * Returns 0 on success or a negative error code on failure. */ static int hdmi_spd_infoframe_unpack(struct hdmi_spd_infoframe *frame, - const void *buffer) + const void *buffer, size_t size) { const u8 *ptr = buffer; int ret; + if (size < HDMI_INFOFRAME_SIZE(SPD)) + return -EINVAL; + if (ptr[0] != HDMI_INFOFRAME_TYPE_SPD || ptr[1] != 1 || ptr[2] != HDMI_SPD_INFOFRAME_SIZE) { @@ -1106,8 +1114,9 @@ static int hdmi_spd_infoframe_unpack(struct hdmi_spd_infoframe *frame, /** * hdmi_audio_infoframe_unpack() - unpack binary buffer to a HDMI AUDIO infoframe - * @buffer: source buffer * @frame: HDMI Audio infoframe + * @buffer: source buffer + * @size: size of buffer * * Unpacks the information contained in binary @buffer into a structured * @frame of the HDMI Audio information frame. @@ -1117,11 +1126,14 @@ static int hdmi_spd_infoframe_unpack(struct hdmi_spd_infoframe *frame, * Returns 0 on success or a negative error code on failure. */ static int hdmi_audio_infoframe_unpack(struct hdmi_audio_infoframe *frame, - const void *buffer) + const void *buffer, size_t size) { const u8 *ptr = buffer; int ret; + if (size < HDMI_INFOFRAME_SIZE(AUDIO)) + return -EINVAL; + if (ptr[0] != HDMI_INFOFRAME_TYPE_AUDIO || ptr[1] != 1 || ptr[2] != HDMI_AUDIO_INFOFRAME_SIZE) { @@ -1151,8 +1163,9 @@ static int hdmi_audio_infoframe_unpack(struct hdmi_audio_infoframe *frame, /** * hdmi_vendor_infoframe_unpack() - unpack binary buffer to a HDMI vendor infoframe - * @buffer: source buffer * @frame: HDMI Vendor infoframe + * @buffer: source buffer + * @size: size of buffer * * Unpacks the information contained in binary @buffer into a structured * @frame of the HDMI Vendor information frame. @@ -1163,7 +1176,7 @@ static int hdmi_audio_infoframe_unpack(struct hdmi_audio_infoframe *frame, */ static int hdmi_vendor_any_infoframe_unpack(union hdmi_vendor_any_infoframe *frame, - const void *buffer) + const void *buffer, size_t size) { const u8 *ptr = buffer; size_t length; @@ -1171,6 +1184,9 @@ hdmi_vendor_any_infoframe_unpack(union hdmi_vendor_any_infoframe *frame, u8 hdmi_video_format; struct hdmi_vendor_infoframe *hvf = &frame->hdmi; + if (size < HDMI_INFOFRAME_HEADER_SIZE) + return -EINVAL; + if (ptr[0] != HDMI_INFOFRAME_TYPE_VENDOR || ptr[1] != 1 || (ptr[2] != 4 && ptr[2] != 5 && ptr[2] != 6)) @@ -1178,6 +1194,9 @@ hdmi_vendor_any_infoframe_unpack(union hdmi_vendor_any_infoframe *frame, length = ptr[2]; + if (size < HDMI_INFOFRAME_HEADER_SIZE + length) + return -EINVAL; + if (hdmi_infoframe_checksum(buffer, HDMI_INFOFRAME_HEADER_SIZE + length) != 0) return -EINVAL; @@ -1224,8 +1243,9 @@ hdmi_vendor_any_infoframe_unpack(union hdmi_vendor_any_infoframe *frame, /** * hdmi_infoframe_unpack() - unpack binary buffer to a HDMI infoframe - * @buffer: source buffer * @frame: HDMI infoframe + * @buffer: source buffer + * @size: size of buffer * * Unpacks the information contained in binary buffer @buffer into a structured * @frame of a HDMI infoframe. @@ -1235,23 +1255,26 @@ hdmi_vendor_any_infoframe_unpack(union hdmi_vendor_any_infoframe *frame, * Returns 0 on success or a negative error code on failure. */ int hdmi_infoframe_unpack(union hdmi_infoframe *frame, - const void *buffer) + const void *buffer, size_t size) { int ret; const u8 *ptr = buffer; + if (size < HDMI_INFOFRAME_HEADER_SIZE) + return -EINVAL; + switch (ptr[0]) { case HDMI_INFOFRAME_TYPE_AVI: - ret = hdmi_avi_infoframe_unpack(&frame->avi, buffer); + ret = hdmi_avi_infoframe_unpack(&frame->avi, buffer, size); break; case HDMI_INFOFRAME_TYPE_SPD: - ret = hdmi_spd_infoframe_unpack(&frame->spd, buffer); + ret = hdmi_spd_infoframe_unpack(&frame->spd, buffer, size); break; case HDMI_INFOFRAME_TYPE_AUDIO: - ret = hdmi_audio_infoframe_unpack(&frame->audio, buffer); + ret = hdmi_audio_infoframe_unpack(&frame->audio, buffer, size); break; case HDMI_INFOFRAME_TYPE_VENDOR: - ret = hdmi_vendor_any_infoframe_unpack(&frame->vendor, buffer); + ret = hdmi_vendor_any_infoframe_unpack(&frame->vendor, buffer, size); break; default: ret = -EINVAL; diff --git a/include/linux/hdmi.h b/include/linux/hdmi.h index d3816170c062..a577d4ae2570 100644 --- a/include/linux/hdmi.h +++ b/include/linux/hdmi.h @@ -333,7 +333,7 @@ union hdmi_infoframe { ssize_t hdmi_infoframe_pack(union hdmi_infoframe *frame, void *buffer, size_t size); int hdmi_infoframe_unpack(union hdmi_infoframe *frame, - const void *buffer); + const void *buffer, size_t size); void hdmi_infoframe_log(const char *level, struct device *dev, union hdmi_infoframe *frame); From patchwork Thu Sep 20 18:51:30 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?VmlsbGUgU3lyasOkbMOk?= X-Patchwork-Id: 10608547 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 1A1E45A4 for ; Thu, 20 Sep 2018 18:52:01 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0A76A2E259 for ; Thu, 20 Sep 2018 18:52:01 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id F30112E2FE; Thu, 20 Sep 2018 18:52:00 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8C7652E308 for ; Thu, 20 Sep 2018 18:52:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2388178AbeIUAgv (ORCPT ); Thu, 20 Sep 2018 20:36:51 -0400 Received: from mga09.intel.com ([134.134.136.24]:10811 "EHLO mga09.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727171AbeIUAgv (ORCPT ); Thu, 20 Sep 2018 20:36:51 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by orsmga102.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 20 Sep 2018 11:51:59 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.54,281,1534834800"; d="scan'208";a="72445215" Received: from stinkbox.fi.intel.com (HELO stinkbox) ([10.237.72.174]) by fmsmga008.fm.intel.com with SMTP; 20 Sep 2018 11:51:56 -0700 Received: by stinkbox (sSMTP sendmail emulation); Thu, 20 Sep 2018 21:51:56 +0300 From: Ville Syrjala To: dri-devel@lists.freedesktop.org Cc: intel-gfx@lists.freedesktop.org, Thierry Reding , Hans Verkuil , linux-media@vger.kernel.org Subject: [PATCH 03/18] video/hdmi: Constify infoframe passed to the log functions Date: Thu, 20 Sep 2018 21:51:30 +0300 Message-Id: <20180920185145.1912-4-ville.syrjala@linux.intel.com> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20180920185145.1912-1-ville.syrjala@linux.intel.com> References: <20180920185145.1912-1-ville.syrjala@linux.intel.com> MIME-Version: 1.0 Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Ville Syrjälä The log functions don't modify the passed in infoframe so make it const. Cc: Thierry Reding Cc: Hans Verkuil Cc: linux-media@vger.kernel.org Signed-off-by: Ville Syrjälä Acked-by: Hans Verkuil --- drivers/video/hdmi.c | 22 +++++++++++----------- include/linux/hdmi.h | 2 +- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c index b5d491014b0b..53e7ee2c83fc 100644 --- a/drivers/video/hdmi.c +++ b/drivers/video/hdmi.c @@ -471,7 +471,7 @@ static const char *hdmi_infoframe_type_get_name(enum hdmi_infoframe_type type) static void hdmi_infoframe_log_header(const char *level, struct device *dev, - struct hdmi_any_infoframe *frame) + const struct hdmi_any_infoframe *frame) { hdmi_log("HDMI infoframe: %s, version %u, length %u\n", hdmi_infoframe_type_get_name(frame->type), @@ -673,10 +673,10 @@ hdmi_content_type_get_name(enum hdmi_content_type content_type) */ static void hdmi_avi_infoframe_log(const char *level, struct device *dev, - struct hdmi_avi_infoframe *frame) + const struct hdmi_avi_infoframe *frame) { hdmi_infoframe_log_header(level, dev, - (struct hdmi_any_infoframe *)frame); + (const struct hdmi_any_infoframe *)frame); hdmi_log(" colorspace: %s\n", hdmi_colorspace_get_name(frame->colorspace)); @@ -750,12 +750,12 @@ static const char *hdmi_spd_sdi_get_name(enum hdmi_spd_sdi sdi) */ static void hdmi_spd_infoframe_log(const char *level, struct device *dev, - struct hdmi_spd_infoframe *frame) + const struct hdmi_spd_infoframe *frame) { u8 buf[17]; hdmi_infoframe_log_header(level, dev, - (struct hdmi_any_infoframe *)frame); + (const struct hdmi_any_infoframe *)frame); memset(buf, 0, sizeof(buf)); @@ -886,10 +886,10 @@ hdmi_audio_coding_type_ext_get_name(enum hdmi_audio_coding_type_ext ctx) */ static void hdmi_audio_infoframe_log(const char *level, struct device *dev, - struct hdmi_audio_infoframe *frame) + const struct hdmi_audio_infoframe *frame) { hdmi_infoframe_log_header(level, dev, - (struct hdmi_any_infoframe *)frame); + (const struct hdmi_any_infoframe *)frame); if (frame->channels) hdmi_log(" channels: %u\n", frame->channels - 1); @@ -949,12 +949,12 @@ hdmi_3d_structure_get_name(enum hdmi_3d_structure s3d_struct) static void hdmi_vendor_any_infoframe_log(const char *level, struct device *dev, - union hdmi_vendor_any_infoframe *frame) + const union hdmi_vendor_any_infoframe *frame) { - struct hdmi_vendor_infoframe *hvf = &frame->hdmi; + const struct hdmi_vendor_infoframe *hvf = &frame->hdmi; hdmi_infoframe_log_header(level, dev, - (struct hdmi_any_infoframe *)frame); + (const struct hdmi_any_infoframe *)frame); if (frame->any.oui != HDMI_IEEE_OUI) { hdmi_log(" not a HDMI vendor infoframe\n"); @@ -984,7 +984,7 @@ hdmi_vendor_any_infoframe_log(const char *level, */ void hdmi_infoframe_log(const char *level, struct device *dev, - union hdmi_infoframe *frame) + const union hdmi_infoframe *frame) { switch (frame->any.type) { case HDMI_INFOFRAME_TYPE_AVI: diff --git a/include/linux/hdmi.h b/include/linux/hdmi.h index a577d4ae2570..bce1abb1fe57 100644 --- a/include/linux/hdmi.h +++ b/include/linux/hdmi.h @@ -335,6 +335,6 @@ hdmi_infoframe_pack(union hdmi_infoframe *frame, void *buffer, size_t size); int hdmi_infoframe_unpack(union hdmi_infoframe *frame, const void *buffer, size_t size); void hdmi_infoframe_log(const char *level, struct device *dev, - union hdmi_infoframe *frame); + const union hdmi_infoframe *frame); #endif /* _DRM_HDMI_H */ From patchwork Thu Sep 20 18:51:31 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?VmlsbGUgU3lyasOkbMOk?= X-Patchwork-Id: 10608553 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 52C9F14DA for ; Thu, 20 Sep 2018 18:52:05 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 40E242E259 for ; Thu, 20 Sep 2018 18:52:05 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 331952E308; Thu, 20 Sep 2018 18:52:05 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id EEC3F2E259 for ; Thu, 20 Sep 2018 18:52:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2388185AbeIUAgy (ORCPT ); Thu, 20 Sep 2018 20:36:54 -0400 Received: from mga05.intel.com ([192.55.52.43]:19952 "EHLO mga05.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727171AbeIUAgy (ORCPT ); Thu, 20 Sep 2018 20:36:54 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by fmsmga105.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 20 Sep 2018 11:52:02 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.54,281,1534834800"; d="scan'208";a="82050480" Received: from stinkbox.fi.intel.com (HELO stinkbox) ([10.237.72.174]) by FMSMGA003.fm.intel.com with SMTP; 20 Sep 2018 11:52:00 -0700 Received: by stinkbox (sSMTP sendmail emulation); Thu, 20 Sep 2018 21:51:59 +0300 From: Ville Syrjala To: dri-devel@lists.freedesktop.org Cc: intel-gfx@lists.freedesktop.org, Thierry Reding , Hans Verkuil , linux-media@vger.kernel.org Subject: [PATCH 04/18] video/hdmi: Constify infoframe passed to the pack functions Date: Thu, 20 Sep 2018 21:51:31 +0300 Message-Id: <20180920185145.1912-5-ville.syrjala@linux.intel.com> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20180920185145.1912-1-ville.syrjala@linux.intel.com> References: <20180920185145.1912-1-ville.syrjala@linux.intel.com> MIME-Version: 1.0 Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Ville Syrjälä Let's make the infoframe pack functions usable with a const infoframe structure. This allows us to precompute the infoframe earlier, and still pack it later when we're no longer allowed to modify the structure. So now we end up with a _check()+_pack_only() or _pack() functions depending on whether you want to precompute the infoframes or not. The names aren't greate but I was lazy and didn't want to change all the drivers. v2: Deal with exynos churn Actually export the new funcs Cc: Thierry Reding Cc: Hans Verkuil Cc: linux-media@vger.kernel.org Signed-off-by: Ville Syrjälä --- drivers/video/hdmi.c | 425 +++++++++++++++++++++++++++++++++++++++++++++++---- include/linux/hdmi.h | 19 ++- 2 files changed, 416 insertions(+), 28 deletions(-) diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c index 53e7ee2c83fc..9507f668a569 100644 --- a/drivers/video/hdmi.c +++ b/drivers/video/hdmi.c @@ -68,8 +68,36 @@ int hdmi_avi_infoframe_init(struct hdmi_avi_infoframe *frame) } EXPORT_SYMBOL(hdmi_avi_infoframe_init); +static int hdmi_avi_infoframe_check_only(const struct hdmi_avi_infoframe *frame) +{ + if (frame->type != HDMI_INFOFRAME_TYPE_AVI || + frame->version != 2 || + frame->length != HDMI_AVI_INFOFRAME_SIZE) + return -EINVAL; + + if (frame->picture_aspect > HDMI_PICTURE_ASPECT_16_9) + return -EINVAL; + + return 0; +} + /** - * hdmi_avi_infoframe_pack() - write HDMI AVI infoframe to binary buffer + * hdmi_avi_infoframe_check() - Check and check a HDMI AVI infoframe + * @frame: HDMI AVI infoframe + * + * Validates that the infoframe is consistent and updates derived fields + * (eg. length) based on other fields. + * + * Returns 0 on success or a negative error code on failure. + */ +int hdmi_avi_infoframe_check(struct hdmi_avi_infoframe *frame) +{ + return hdmi_avi_infoframe_check_only(frame); +} +EXPORT_SYMBOL(hdmi_avi_infoframe_check); + +/** + * hdmi_avi_infoframe_pack_only() - write HDMI AVI infoframe to binary buffer * @frame: HDMI AVI infoframe * @buffer: destination buffer * @size: size of buffer @@ -82,20 +110,22 @@ EXPORT_SYMBOL(hdmi_avi_infoframe_init); * Returns the number of bytes packed into the binary buffer or a negative * error code on failure. */ -ssize_t hdmi_avi_infoframe_pack(struct hdmi_avi_infoframe *frame, void *buffer, - size_t size) +ssize_t hdmi_avi_infoframe_pack_only(const struct hdmi_avi_infoframe *frame, + void *buffer, size_t size) { u8 *ptr = buffer; size_t length; + int ret; + + ret = hdmi_avi_infoframe_check_only(frame); + if (ret) + return ret; length = HDMI_INFOFRAME_HEADER_SIZE + frame->length; if (size < length) return -ENOSPC; - if (frame->picture_aspect > HDMI_PICTURE_ASPECT_16_9) - return -EINVAL; - memset(buffer, 0, size); ptr[0] = frame->type; @@ -152,6 +182,36 @@ ssize_t hdmi_avi_infoframe_pack(struct hdmi_avi_infoframe *frame, void *buffer, return length; } +EXPORT_SYMBOL(hdmi_avi_infoframe_pack_only); + +/** + * hdmi_avi_infoframe_pack() - Check and check a HDMI AVI infoframe, + * and write it to binary buffer + * @frame: HDMI AVI infoframe + * @buffer: destination buffer + * @size: size of buffer + * + * Validates that the infoframe is consistent and updates derived fields + * (eg. length) based on other fields, after which packs the information + * contained in the @frame structure into a binary representation that + * can be written into the corresponding controller registers. Also + * computes the checksum as required by section 5.3.5 of the HDMI 1.4 + * specification. + * + * Returns the number of bytes packed into the binary buffer or a negative + * error code on failure. + */ +ssize_t hdmi_avi_infoframe_pack(struct hdmi_avi_infoframe *frame, + void *buffer, size_t size) +{ + int ret; + + ret = hdmi_avi_infoframe_check(frame); + if (ret) + return ret; + + return hdmi_avi_infoframe_pack_only(frame, buffer, size); +} EXPORT_SYMBOL(hdmi_avi_infoframe_pack); /** @@ -178,8 +238,33 @@ int hdmi_spd_infoframe_init(struct hdmi_spd_infoframe *frame, } EXPORT_SYMBOL(hdmi_spd_infoframe_init); +static int hdmi_spd_infoframe_check_only(const struct hdmi_spd_infoframe *frame) +{ + if (frame->type != HDMI_INFOFRAME_TYPE_SPD || + frame->version != 1 || + frame->length != HDMI_SPD_INFOFRAME_SIZE) + return -EINVAL; + + return 0; +} + /** - * hdmi_spd_infoframe_pack() - write HDMI SPD infoframe to binary buffer + * hdmi_spd_infoframe_check() - Check and check a HDMI SPD infoframe + * @frame: HDMI SPD infoframe + * + * Validates that the infoframe is consistent and updates derived fields + * (eg. length) based on other fields. + * + * Returns 0 on success or a negative error code on failure. + */ +int hdmi_spd_infoframe_check(struct hdmi_spd_infoframe *frame) +{ + return hdmi_spd_infoframe_check_only(frame); +} +EXPORT_SYMBOL(hdmi_spd_infoframe_check); + +/** + * hdmi_spd_infoframe_pack_only() - write HDMI SPD infoframe to binary buffer * @frame: HDMI SPD infoframe * @buffer: destination buffer * @size: size of buffer @@ -192,11 +277,16 @@ EXPORT_SYMBOL(hdmi_spd_infoframe_init); * Returns the number of bytes packed into the binary buffer or a negative * error code on failure. */ -ssize_t hdmi_spd_infoframe_pack(struct hdmi_spd_infoframe *frame, void *buffer, - size_t size) +ssize_t hdmi_spd_infoframe_pack_only(const struct hdmi_spd_infoframe *frame, + void *buffer, size_t size) { u8 *ptr = buffer; size_t length; + int ret; + + ret = hdmi_spd_infoframe_check_only(frame); + if (ret) + return ret; length = HDMI_INFOFRAME_HEADER_SIZE + frame->length; @@ -222,6 +312,36 @@ ssize_t hdmi_spd_infoframe_pack(struct hdmi_spd_infoframe *frame, void *buffer, return length; } +EXPORT_SYMBOL(hdmi_spd_infoframe_pack_only); + +/** + * hdmi_spd_infoframe_pack() - Check and check a HDMI SPD infoframe, + * and write it to binary buffer + * @frame: HDMI SPD infoframe + * @buffer: destination buffer + * @size: size of buffer + * + * Validates that the infoframe is consistent and updates derived fields + * (eg. length) based on other fields, after which packs the information + * contained in the @frame structure into a binary representation that + * can be written into the corresponding controller registers. Also + * computes the checksum as required by section 5.3.5 of the HDMI 1.4 + * specification. + * + * Returns the number of bytes packed into the binary buffer or a negative + * error code on failure. + */ +ssize_t hdmi_spd_infoframe_pack(struct hdmi_spd_infoframe *frame, + void *buffer, size_t size) +{ + int ret; + + ret = hdmi_spd_infoframe_check(frame); + if (ret) + return ret; + + return hdmi_spd_infoframe_pack_only(frame, buffer, size); +} EXPORT_SYMBOL(hdmi_spd_infoframe_pack); /** @@ -242,8 +362,33 @@ int hdmi_audio_infoframe_init(struct hdmi_audio_infoframe *frame) } EXPORT_SYMBOL(hdmi_audio_infoframe_init); +static int hdmi_audio_infoframe_check_only(const struct hdmi_audio_infoframe *frame) +{ + if (frame->type != HDMI_INFOFRAME_TYPE_AUDIO || + frame->version != 1 || + frame->length != HDMI_AUDIO_INFOFRAME_SIZE) + return -EINVAL; + + return 0; +} + +/** + * hdmi_audio_infoframe_check() - Check and check a HDMI audio infoframe + * @frame: HDMI audio infoframe + * + * Validates that the infoframe is consistent and updates derived fields + * (eg. length) based on other fields. + * + * Returns 0 on success or a negative error code on failure. + */ +int hdmi_audio_infoframe_check(struct hdmi_audio_infoframe *frame) +{ + return hdmi_audio_infoframe_check_only(frame); +} +EXPORT_SYMBOL(hdmi_audio_infoframe_check); + /** - * hdmi_audio_infoframe_pack() - write HDMI audio infoframe to binary buffer + * hdmi_audio_infoframe_pack_only() - write HDMI audio infoframe to binary buffer * @frame: HDMI audio infoframe * @buffer: destination buffer * @size: size of buffer @@ -256,12 +401,17 @@ EXPORT_SYMBOL(hdmi_audio_infoframe_init); * Returns the number of bytes packed into the binary buffer or a negative * error code on failure. */ -ssize_t hdmi_audio_infoframe_pack(struct hdmi_audio_infoframe *frame, - void *buffer, size_t size) +ssize_t hdmi_audio_infoframe_pack_only(const struct hdmi_audio_infoframe *frame, + void *buffer, size_t size) { unsigned char channels; u8 *ptr = buffer; size_t length; + int ret; + + ret = hdmi_audio_infoframe_check_only(frame); + if (ret) + return ret; length = HDMI_INFOFRAME_HEADER_SIZE + frame->length; @@ -297,6 +447,36 @@ ssize_t hdmi_audio_infoframe_pack(struct hdmi_audio_infoframe *frame, return length; } +EXPORT_SYMBOL(hdmi_audio_infoframe_pack_only); + +/** + * hdmi_audio_infoframe_pack() - Check and check a HDMI Audio infoframe, + * and write it to binary buffer + * @frame: HDMI Audio infoframe + * @buffer: destination buffer + * @size: size of buffer + * + * Validates that the infoframe is consistent and updates derived fields + * (eg. length) based on other fields, after which packs the information + * contained in the @frame structure into a binary representation that + * can be written into the corresponding controller registers. Also + * computes the checksum as required by section 5.3.5 of the HDMI 1.4 + * specification. + * + * Returns the number of bytes packed into the binary buffer or a negative + * error code on failure. + */ +ssize_t hdmi_audio_infoframe_pack(struct hdmi_audio_infoframe *frame, + void *buffer, size_t size) +{ + int ret; + + ret = hdmi_audio_infoframe_check(frame); + if (ret) + return ret; + + return hdmi_audio_infoframe_pack_only(frame, buffer, size); +} EXPORT_SYMBOL(hdmi_audio_infoframe_pack); /** @@ -319,6 +499,7 @@ int hdmi_vendor_infoframe_init(struct hdmi_vendor_infoframe *frame) * value */ frame->s3d_struct = HDMI_3D_STRUCTURE_INVALID; + frame->length = 4; return 0; } @@ -335,8 +516,42 @@ static int hdmi_vendor_infoframe_length(const struct hdmi_vendor_infoframe *fram return 4; } +static int hdmi_vendor_infoframe_check_only(const struct hdmi_vendor_infoframe *frame) +{ + if (frame->type != HDMI_INFOFRAME_TYPE_VENDOR || + frame->version != 1 || + frame->oui != HDMI_IEEE_OUI) + return -EINVAL; + + /* only one of those can be supplied */ + if (frame->vic != 0 && frame->s3d_struct != HDMI_3D_STRUCTURE_INVALID) + return -EINVAL; + + if (frame->length != hdmi_vendor_infoframe_length(frame)) + return -EINVAL; + + return 0; +} + /** - * hdmi_vendor_infoframe_pack() - write a HDMI vendor infoframe to binary buffer + * hdmi_vendor_infoframe_check() - Check and check a HDMI vendor infoframe + * @frame: HDMI infoframe + * + * Validates that the infoframe is consistent and updates derived fields + * (eg. length) based on other fields. + * + * Returns 0 on success or a negative error code on failure. + */ +int hdmi_vendor_infoframe_check(struct hdmi_vendor_infoframe *frame) +{ + frame->length = hdmi_vendor_infoframe_length(frame); + + return hdmi_vendor_infoframe_check_only(frame); +} +EXPORT_SYMBOL(hdmi_vendor_infoframe_check); + +/** + * hdmi_vendor_infoframe_pack_only() - write a HDMI vendor infoframe to binary buffer * @frame: HDMI infoframe * @buffer: destination buffer * @size: size of buffer @@ -349,17 +564,16 @@ static int hdmi_vendor_infoframe_length(const struct hdmi_vendor_infoframe *fram * Returns the number of bytes packed into the binary buffer or a negative * error code on failure. */ -ssize_t hdmi_vendor_infoframe_pack(struct hdmi_vendor_infoframe *frame, - void *buffer, size_t size) +ssize_t hdmi_vendor_infoframe_pack_only(const struct hdmi_vendor_infoframe *frame, + void *buffer, size_t size) { u8 *ptr = buffer; size_t length; + int ret; - /* only one of those can be supplied */ - if (frame->vic != 0 && frame->s3d_struct != HDMI_3D_STRUCTURE_INVALID) - return -EINVAL; - - frame->length = hdmi_vendor_infoframe_length(frame); + ret = hdmi_vendor_infoframe_check_only(frame); + if (ret) + return ret; length = HDMI_INFOFRAME_HEADER_SIZE + frame->length; @@ -394,24 +608,134 @@ ssize_t hdmi_vendor_infoframe_pack(struct hdmi_vendor_infoframe *frame, return length; } +EXPORT_SYMBOL(hdmi_vendor_infoframe_pack_only); + +/** + * hdmi_vendor_infoframe_pack() - Check and check a HDMI Vendor infoframe, + * and write it to binary buffer + * @frame: HDMI Vendor infoframe + * @buffer: destination buffer + * @size: size of buffer + * + * Validates that the infoframe is consistent and updates derived fields + * (eg. length) based on other fields, after which packs the information + * contained in the @frame structure into a binary representation that + * can be written into the corresponding controller registers. Also + * computes the checksum as required by section 5.3.5 of the HDMI 1.4 + * specification. + * + * Returns the number of bytes packed into the binary buffer or a negative + * error code on failure. + */ +ssize_t hdmi_vendor_infoframe_pack(struct hdmi_vendor_infoframe *frame, + void *buffer, size_t size) +{ + int ret; + + ret = hdmi_vendor_infoframe_check(frame); + if (ret) + return ret; + + return hdmi_vendor_infoframe_pack_only(frame, buffer, size); +} EXPORT_SYMBOL(hdmi_vendor_infoframe_pack); +static int +hdmi_vendor_any_infoframe_check_only(const union hdmi_vendor_any_infoframe *frame) +{ + if (frame->any.type != HDMI_INFOFRAME_TYPE_VENDOR || + frame->any.version != 1) + return -EINVAL; + + return 0; +} + /* - * hdmi_vendor_any_infoframe_pack() - write a vendor infoframe to binary buffer + * hdmi_vendor_any_infoframe_check() - check and check a vendor infoframe + */ +static int +hdmi_vendor_any_infoframe_check(union hdmi_vendor_any_infoframe *frame) +{ + int ret; + + ret = hdmi_vendor_any_infoframe_check_only(frame); + if (ret) + return ret; + + /* we only know about HDMI vendor infoframes */ + if (frame->any.oui != HDMI_IEEE_OUI) + return -EINVAL; + + return hdmi_vendor_infoframe_check(&frame->hdmi); +} + +/* + * hdmi_vendor_any_infoframe_pack_only() - write a vendor infoframe to binary buffer */ static ssize_t -hdmi_vendor_any_infoframe_pack(union hdmi_vendor_any_infoframe *frame, - void *buffer, size_t size) +hdmi_vendor_any_infoframe_pack_only(const union hdmi_vendor_any_infoframe *frame, + void *buffer, size_t size) { + int ret; + + ret = hdmi_vendor_any_infoframe_check_only(frame); + if (ret) + return ret; + /* we only know about HDMI vendor infoframes */ if (frame->any.oui != HDMI_IEEE_OUI) return -EINVAL; - return hdmi_vendor_infoframe_pack(&frame->hdmi, buffer, size); + return hdmi_vendor_infoframe_pack_only(&frame->hdmi, buffer, size); +} + +/* + * hdmi_vendor_any_infoframe_pack() - check and check a vendor infoframe, + * and write it to binary buffer + */ +static ssize_t +hdmi_vendor_any_infoframe_pack(union hdmi_vendor_any_infoframe *frame, + void *buffer, size_t size) +{ + int ret; + + ret = hdmi_vendor_any_infoframe_check(frame); + if (ret) + return ret; + + return hdmi_vendor_any_infoframe_pack_only(frame, buffer, size); +} + +/** + * hdmi_infoframe_check() - Check check a HDMI infoframe + * @frame: HDMI infoframe + * + * Validates that the infoframe is consistent and updates derived fields + * (eg. length) based on other fields. + * + * Returns 0 on success or a negative error code on failure. + */ +int +hdmi_infoframe_check(union hdmi_infoframe *frame) +{ + switch (frame->any.type) { + case HDMI_INFOFRAME_TYPE_AVI: + return hdmi_avi_infoframe_check(&frame->avi); + case HDMI_INFOFRAME_TYPE_SPD: + return hdmi_spd_infoframe_check(&frame->spd); + case HDMI_INFOFRAME_TYPE_AUDIO: + return hdmi_audio_infoframe_check(&frame->audio); + case HDMI_INFOFRAME_TYPE_VENDOR: + return hdmi_vendor_any_infoframe_check(&frame->vendor); + default: + WARN(1, "Bad infoframe type %d\n", frame->any.type); + return -EINVAL; + } } +EXPORT_SYMBOL(hdmi_infoframe_check); /** - * hdmi_infoframe_pack() - write a HDMI infoframe to binary buffer + * hdmi_infoframe_pack_only() - write a HDMI infoframe to binary buffer * @frame: HDMI infoframe * @buffer: destination buffer * @size: size of buffer @@ -425,7 +749,56 @@ hdmi_vendor_any_infoframe_pack(union hdmi_vendor_any_infoframe *frame, * error code on failure. */ ssize_t -hdmi_infoframe_pack(union hdmi_infoframe *frame, void *buffer, size_t size) +hdmi_infoframe_pack_only(const union hdmi_infoframe *frame, void *buffer, size_t size) +{ + ssize_t length; + + switch (frame->any.type) { + case HDMI_INFOFRAME_TYPE_AVI: + length = hdmi_avi_infoframe_pack_only(&frame->avi, + buffer, size); + break; + case HDMI_INFOFRAME_TYPE_SPD: + length = hdmi_spd_infoframe_pack_only(&frame->spd, + buffer, size); + break; + case HDMI_INFOFRAME_TYPE_AUDIO: + length = hdmi_audio_infoframe_pack_only(&frame->audio, + buffer, size); + break; + case HDMI_INFOFRAME_TYPE_VENDOR: + length = hdmi_vendor_any_infoframe_pack_only(&frame->vendor, + buffer, size); + break; + default: + WARN(1, "Bad infoframe type %d\n", frame->any.type); + length = -EINVAL; + } + + return length; +} +EXPORT_SYMBOL(hdmi_infoframe_pack_only); + +/** + * hdmi_infoframe_pack() - Check check a HDMI infoframe, + * and write it to binary buffer + * @frame: HDMI infoframe + * @buffer: destination buffer + * @size: size of buffer + * + * Validates that the infoframe is consistent and updates derived fields + * (eg. length) based on other fields, after which packs the information + * contained in the @frame structure into a binary representation that + * can be written into the corresponding controller registers. Also + * computes the checksum as required by section 5.3.5 of the HDMI 1.4 + * specification. + * + * Returns the number of bytes packed into the binary buffer or a negative + * error code on failure. + */ +ssize_t +hdmi_infoframe_pack(union hdmi_infoframe *frame, + void *buffer, size_t size) { ssize_t length; diff --git a/include/linux/hdmi.h b/include/linux/hdmi.h index bce1abb1fe57..c76b50a48e48 100644 --- a/include/linux/hdmi.h +++ b/include/linux/hdmi.h @@ -163,6 +163,9 @@ struct hdmi_avi_infoframe { int hdmi_avi_infoframe_init(struct hdmi_avi_infoframe *frame); ssize_t hdmi_avi_infoframe_pack(struct hdmi_avi_infoframe *frame, void *buffer, size_t size); +ssize_t hdmi_avi_infoframe_pack_only(const struct hdmi_avi_infoframe *frame, + void *buffer, size_t size); +int hdmi_avi_infoframe_check(struct hdmi_avi_infoframe *frame); enum hdmi_spd_sdi { HDMI_SPD_SDI_UNKNOWN, @@ -194,6 +197,9 @@ int hdmi_spd_infoframe_init(struct hdmi_spd_infoframe *frame, const char *vendor, const char *product); ssize_t hdmi_spd_infoframe_pack(struct hdmi_spd_infoframe *frame, void *buffer, size_t size); +ssize_t hdmi_spd_infoframe_pack_only(const struct hdmi_spd_infoframe *frame, + void *buffer, size_t size); +int hdmi_spd_infoframe_check(struct hdmi_spd_infoframe *frame); enum hdmi_audio_coding_type { HDMI_AUDIO_CODING_TYPE_STREAM, @@ -272,6 +278,9 @@ struct hdmi_audio_infoframe { int hdmi_audio_infoframe_init(struct hdmi_audio_infoframe *frame); ssize_t hdmi_audio_infoframe_pack(struct hdmi_audio_infoframe *frame, void *buffer, size_t size); +ssize_t hdmi_audio_infoframe_pack_only(const struct hdmi_audio_infoframe *frame, + void *buffer, size_t size); +int hdmi_audio_infoframe_check(struct hdmi_audio_infoframe *frame); enum hdmi_3d_structure { HDMI_3D_STRUCTURE_INVALID = -1, @@ -299,6 +308,9 @@ struct hdmi_vendor_infoframe { int hdmi_vendor_infoframe_init(struct hdmi_vendor_infoframe *frame); ssize_t hdmi_vendor_infoframe_pack(struct hdmi_vendor_infoframe *frame, void *buffer, size_t size); +ssize_t hdmi_vendor_infoframe_pack_only(const struct hdmi_vendor_infoframe *frame, + void *buffer, size_t size); +int hdmi_vendor_infoframe_check(struct hdmi_vendor_infoframe *frame); union hdmi_vendor_any_infoframe { struct { @@ -330,8 +342,11 @@ union hdmi_infoframe { struct hdmi_audio_infoframe audio; }; -ssize_t -hdmi_infoframe_pack(union hdmi_infoframe *frame, void *buffer, size_t size); +ssize_t hdmi_infoframe_pack(union hdmi_infoframe *frame, void *buffer, + size_t size); +ssize_t hdmi_infoframe_pack_only(const union hdmi_infoframe *frame, + void *buffer, size_t size); +int hdmi_infoframe_check(union hdmi_infoframe *frame); int hdmi_infoframe_unpack(union hdmi_infoframe *frame, const void *buffer, size_t size); void hdmi_infoframe_log(const char *level, struct device *dev, From patchwork Thu Sep 20 18:51:32 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?VmlsbGUgU3lyasOkbMOk?= X-Patchwork-Id: 10608561 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 97B6214DA for ; Thu, 20 Sep 2018 18:52:09 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 81DBA2E259 for ; Thu, 20 Sep 2018 18:52:09 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 760E62E307; Thu, 20 Sep 2018 18:52:09 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 24CDF2E2FE for ; Thu, 20 Sep 2018 18:52:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2388193AbeIUAg7 (ORCPT ); Thu, 20 Sep 2018 20:36:59 -0400 Received: from mga01.intel.com ([192.55.52.88]:20745 "EHLO mga01.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727171AbeIUAg7 (ORCPT ); Thu, 20 Sep 2018 20:36:59 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga001.jf.intel.com ([10.7.209.18]) by fmsmga101.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 20 Sep 2018 11:52:07 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.54,281,1534834800"; d="scan'208";a="92310780" Received: from stinkbox.fi.intel.com (HELO stinkbox) ([10.237.72.174]) by orsmga001.jf.intel.com with SMTP; 20 Sep 2018 11:52:03 -0700 Received: by stinkbox (sSMTP sendmail emulation); Thu, 20 Sep 2018 21:52:03 +0300 From: Ville Syrjala To: dri-devel@lists.freedesktop.org Cc: intel-gfx@lists.freedesktop.org, Thierry Reding , Hans Verkuil , linux-media@vger.kernel.org Subject: [PATCH 05/18] video/hdmi: Add an enum for HDMI packet types Date: Thu, 20 Sep 2018 21:51:32 +0300 Message-Id: <20180920185145.1912-6-ville.syrjala@linux.intel.com> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20180920185145.1912-1-ville.syrjala@linux.intel.com> References: <20180920185145.1912-1-ville.syrjala@linux.intel.com> MIME-Version: 1.0 Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Ville Syrjälä We'll be wanting to send more than just infoframes over HDMI. So add an enum for other packet types. TODO: Maybe just include the infoframe types in the packet type enum and get rid of the infoframe type enum? Cc: Thierry Reding Cc: Hans Verkuil Cc: linux-media@vger.kernel.org Signed-off-by: Ville Syrjälä --- include/linux/hdmi.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/include/linux/hdmi.h b/include/linux/hdmi.h index c76b50a48e48..80521d9591a1 100644 --- a/include/linux/hdmi.h +++ b/include/linux/hdmi.h @@ -27,6 +27,21 @@ #include #include +enum hdmi_packet_type { + HDMI_PACKET_TYPE_NULL = 0x00, + HDMI_PACKET_TYPE_AUDIO_CLOCK_REGEN = 0x01, + HDMI_PACKET_TYPE_AUDIO_SAMPLE = 0x02, + HDMI_PACKET_TYPE_GENERAL_CONTROL = 0x03, + HDMI_PACKET_TYPE_AUDIO_CP = 0x04, + HDMI_PACKET_TYPE_ISRC1 = 0x05, + HDMI_PACKET_TYPE_ISRC2 = 0x06, + HDMI_PACKET_TYPE_ONE_BIT_AUDIO_SAMPLE = 0x07, + HDMI_PACKET_TYPE_DST_AUDIO = 0x08, + HDMI_PACKET_TYPE_HBR_AUDIO_STREAM = 0x09, + HDMI_PACKET_TYPE_GAMUT_METADATA = 0x0a, + /* + enum hdmi_infoframe_type */ +}; + enum hdmi_infoframe_type { HDMI_INFOFRAME_TYPE_VENDOR = 0x81, HDMI_INFOFRAME_TYPE_AVI = 0x82, From patchwork Thu Sep 20 18:51:33 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?VmlsbGUgU3lyasOkbMOk?= X-Patchwork-Id: 10608565 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A1B4E14DA for ; Thu, 20 Sep 2018 18:52:13 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 90DB32E23A for ; Thu, 20 Sep 2018 18:52:13 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 835D72E307; Thu, 20 Sep 2018 18:52:13 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AA3752E23A for ; Thu, 20 Sep 2018 18:52:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2388195AbeIUAhD (ORCPT ); Thu, 20 Sep 2018 20:37:03 -0400 Received: from mga03.intel.com ([134.134.136.65]:25854 "EHLO mga03.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727171AbeIUAhD (ORCPT ); Thu, 20 Sep 2018 20:37:03 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga002.jf.intel.com ([10.7.209.21]) by orsmga103.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 20 Sep 2018 11:52:11 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.54,281,1534834800"; d="scan'208";a="93496372" Received: from stinkbox.fi.intel.com (HELO stinkbox) ([10.237.72.174]) by orsmga002.jf.intel.com with SMTP; 20 Sep 2018 11:52:08 -0700 Received: by stinkbox (sSMTP sendmail emulation); Thu, 20 Sep 2018 21:52:07 +0300 From: Ville Syrjala To: dri-devel@lists.freedesktop.org Cc: intel-gfx@lists.freedesktop.org, Thierry Reding , Hans Verkuil , linux-media@vger.kernel.org Subject: [PATCH 06/18] video/hdmi: Handle the MPEG Source infoframe Date: Thu, 20 Sep 2018 21:51:33 +0300 Message-Id: <20180920185145.1912-7-ville.syrjala@linux.intel.com> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20180920185145.1912-1-ville.syrjala@linux.intel.com> References: <20180920185145.1912-1-ville.syrjala@linux.intel.com> MIME-Version: 1.0 Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Ville Syrjälä Add the code to deal with the MPEG source infoframe. Blindly typed from the spec, and totally untested. Cc: Thierry Reding Cc: Hans Verkuil Cc: linux-media@vger.kernel.org Signed-off-by: Ville Syrjälä --- drivers/video/hdmi.c | 229 +++++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/hdmi.h | 27 ++++++ 2 files changed, 256 insertions(+) diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c index 9507f668a569..3d24c7746c51 100644 --- a/drivers/video/hdmi.c +++ b/drivers/video/hdmi.c @@ -706,6 +706,131 @@ hdmi_vendor_any_infoframe_pack(union hdmi_vendor_any_infoframe *frame, return hdmi_vendor_any_infoframe_pack_only(frame, buffer, size); } +/** + * hdmi_mpeg_source_infoframe_init() - initialize an HDMI MPEG Source infoframe + * @frame: HDMI MPEG Source infoframe + * + * Returns 0 on success or a negative error code on failure. + */ +int hdmi_mpeg_source_infoframe_init(struct hdmi_mpeg_source_infoframe *frame) +{ + memset(frame, 0, sizeof(*frame)); + + frame->type = HDMI_INFOFRAME_TYPE_MPEG_SOURCE; + frame->version = 1; + frame->length = HDMI_MPEG_SOURCE_INFOFRAME_SIZE; + + return 0; +} +EXPORT_SYMBOL(hdmi_mpeg_source_infoframe_init); + +static int hdmi_mpeg_source_infoframe_check_only(const struct hdmi_mpeg_source_infoframe *frame) +{ + if (frame->type != HDMI_INFOFRAME_TYPE_MPEG_SOURCE || + frame->version != 1 || + frame->length != HDMI_MPEG_SOURCE_INFOFRAME_SIZE) + return -EINVAL; + + return 0; +} + +/** + * hdmi_mpeg_source_infoframe_check() - Check and check a HDMI MPEG Source infoframe + * @frame: HDMI MPEG Source infoframe + * + * Validates that the infoframe is consistent and updates derived fields + * (eg. length) based on other fields. + * + * Returns 0 on success or a negative error code on failure. + */ +int hdmi_mpeg_source_infoframe_check(struct hdmi_mpeg_source_infoframe *frame) +{ + return hdmi_mpeg_source_infoframe_check_only(frame); +} +EXPORT_SYMBOL(hdmi_mpeg_source_infoframe_check); + +/** + * hdmi_mpeg_source_infoframe_pack_only() - write HDMI MPEG Source infoframe to binary buffer + * @frame: HDMI MPEG Source infoframe + * @buffer: destination buffer + * @size: size of buffer + * + * Packs the information contained in the @frame structure into a binary + * representation that can be written into the corresponding controller + * registers. Also computes the checksum as required by section 5.3.5 of + * the HDMI 1.4 specification. + * + * Returns the number of bytes packed into the binary buffer or a negative + * error code on failure. + */ +ssize_t hdmi_mpeg_source_infoframe_pack_only(const struct hdmi_mpeg_source_infoframe *frame, + void *buffer, size_t size) +{ + u8 *ptr = buffer; + size_t length; + int ret; + + ret = hdmi_mpeg_source_infoframe_check_only(frame); + if (ret) + return ret; + + length = HDMI_INFOFRAME_HEADER_SIZE + frame->length; + + if (size < length) + return -ENOSPC; + + memset(buffer, 0, size); + + ptr[0] = frame->type; + ptr[1] = frame->version; + ptr[2] = frame->length; + ptr[3] = 0; /* checksum */ + + /* start infoframe payload */ + ptr += HDMI_INFOFRAME_HEADER_SIZE; + + ptr[0] = frame->mpeg_bit_rate >> 0; + ptr[1] = frame->mpeg_bit_rate >> 8; + ptr[2] = frame->mpeg_bit_rate >> 16; + ptr[3] = frame->mpeg_bit_rate >> 24; + ptr[4] = (frame->field_repeat << 4) | frame->mpeg_frame; + + hdmi_infoframe_set_checksum(buffer, length); + + return length; +} +EXPORT_SYMBOL(hdmi_mpeg_source_infoframe_pack_only); + +/** + * hdmi_mpeg_source_infoframe_pack() - Check and check a HDMI MPEG Source infoframe, + * and write it to binary buffer + * @frame: HDMI MPEG Source infoframe + * @buffer: destination buffer + * @size: size of buffer + * + * Validates that the infoframe is consistent and updates derived fields + * (eg. length) based on other fields, after which packs the information + * contained in the @frame structure into a binary representation that + * can be written into the corresponding controller registers. Also + * computes the checksum as required by section 5.3.5 of the HDMI 1.4 + * specification. + * + * Returns the number of bytes packed into the binary buffer or a negative + * error code on failure. + */ +ssize_t hdmi_mpeg_source_infoframe_pack(struct hdmi_mpeg_source_infoframe *frame, + void *buffer, size_t size) +{ + int ret; + + ret = hdmi_mpeg_source_infoframe_check(frame); + if (ret) + return ret; + + return hdmi_mpeg_source_infoframe_pack_only(frame, buffer, size); +} +EXPORT_SYMBOL(hdmi_mpeg_source_infoframe_pack); + /** * hdmi_infoframe_check() - Check check a HDMI infoframe * @frame: HDMI infoframe @@ -727,6 +852,8 @@ hdmi_infoframe_check(union hdmi_infoframe *frame) return hdmi_audio_infoframe_check(&frame->audio); case HDMI_INFOFRAME_TYPE_VENDOR: return hdmi_vendor_any_infoframe_check(&frame->vendor); + case HDMI_INFOFRAME_TYPE_MPEG_SOURCE: + return hdmi_mpeg_source_infoframe_check(&frame->mpeg_source); default: WARN(1, "Bad infoframe type %d\n", frame->any.type); return -EINVAL; @@ -770,6 +897,10 @@ hdmi_infoframe_pack_only(const union hdmi_infoframe *frame, void *buffer, size_t length = hdmi_vendor_any_infoframe_pack_only(&frame->vendor, buffer, size); break; + case HDMI_INFOFRAME_TYPE_MPEG_SOURCE: + length = hdmi_mpeg_source_infoframe_pack_only(&frame->mpeg_source, + buffer, size); + break; default: WARN(1, "Bad infoframe type %d\n", frame->any.type); length = -EINVAL; @@ -816,6 +947,10 @@ hdmi_infoframe_pack(union hdmi_infoframe *frame, length = hdmi_vendor_any_infoframe_pack(&frame->vendor, buffer, size); break; + case HDMI_INFOFRAME_TYPE_MPEG_SOURCE: + length = hdmi_mpeg_source_infoframe_pack(&frame->mpeg_source, + buffer, size); + break; default: WARN(1, "Bad infoframe type %d\n", frame->any.type); length = -EINVAL; @@ -838,6 +973,8 @@ static const char *hdmi_infoframe_type_get_name(enum hdmi_infoframe_type type) return "Source Product Description (SPD)"; case HDMI_INFOFRAME_TYPE_AUDIO: return "Audio"; + case HDMI_INFOFRAME_TYPE_MPEG_SOURCE: + return "MPEG Source"; } return "Reserved"; } @@ -1349,6 +1486,46 @@ hdmi_vendor_any_infoframe_log(const char *level, } } +static const char * +hdmi_mpeg_frame_get_name(enum hdmi_mpeg_frame frame) +{ + if (frame < 0 || frame > 3) + return "invalid"; + + switch (frame) { + case HDMI_MPEG_FRAME_UNKNOWN: + return "Unknown"; + case HDMI_MPEG_FRAME_I_PICTURE: + return "I Picture"; + case HDMI_MPEG_FRAME_B_PICTURE: + return "B Picture"; + case HDMI_MPEG_FRAME_P_PICTURE: + return "P Picture"; + } + return "Reserved"; +} + +/** + * hdmi_mpeg_source_infoframe_log() - log info of HDMI MPEG Source infoframe + * @level: logging level + * @dev: device + * @frame: HDMI MPEG Source infoframe + */ +static void hdmi_mpeg_source_infoframe_log(const char *level, + struct device *dev, + const struct hdmi_mpeg_source_infoframe *frame) +{ + hdmi_infoframe_log_header(level, dev, + (const struct hdmi_any_infoframe *)frame); + + hdmi_log(" MPEG bit rate: %d Hz\n", + frame->mpeg_bit_rate); + hdmi_log(" MPEG frame: %s\n", + hdmi_mpeg_frame_get_name(frame->mpeg_frame)); + hdmi_log(" field repeat: %s\n", + frame->field_repeat ? "Yes" : "No"); +} + /** * hdmi_infoframe_log() - log info of HDMI infoframe * @level: logging level @@ -1372,6 +1549,9 @@ void hdmi_infoframe_log(const char *level, case HDMI_INFOFRAME_TYPE_VENDOR: hdmi_vendor_any_infoframe_log(level, dev, &frame->vendor); break; + case HDMI_INFOFRAME_TYPE_MPEG_SOURCE: + hdmi_mpeg_source_infoframe_log(level, dev, &frame->mpeg_source); + break; } } EXPORT_SYMBOL(hdmi_infoframe_log); @@ -1614,6 +1794,52 @@ hdmi_vendor_any_infoframe_unpack(union hdmi_vendor_any_infoframe *frame, return 0; } +/** + * hdmi_mpeg_source_infoframe_unpack() - unpack binary buffer to a HDMI MPEG Source infoframe + * @frame: HDMI MPEG Source infoframe + * @buffer: source buffer + * @size: size of buffer + * + * Unpacks the information contained in binary @buffer into a structured + * @frame of the HDMI MPEG Source information frame. + * Also verifies the checksum as required by section 5.3.5 of the HDMI 1.4 + * specification. + * + * Returns 0 on success or a negative error code on failure. + */ +static int hdmi_mpeg_source_infoframe_unpack(struct hdmi_mpeg_source_infoframe *frame, + const void *buffer, size_t size) +{ + const u8 *ptr = buffer; + int ret; + + if (size < HDMI_INFOFRAME_SIZE(MPEG_SOURCE)) + return -EINVAL; + + if (ptr[0] != HDMI_INFOFRAME_TYPE_MPEG_SOURCE || + ptr[1] != 1 || + ptr[2] != HDMI_MPEG_SOURCE_INFOFRAME_SIZE) { + return -EINVAL; + } + + if (hdmi_infoframe_checksum(buffer, HDMI_INFOFRAME_SIZE(MPEG_SOURCE)) != 0) + return -EINVAL; + + ret = hdmi_mpeg_source_infoframe_init(frame); + if (ret) + return ret; + + ptr += HDMI_INFOFRAME_HEADER_SIZE; + + frame->mpeg_bit_rate = + (ptr[0] << 0) | (ptr[1] << 8) | + (ptr[2] << 16) | (ptr[3] << 24); + frame->mpeg_frame = ptr[4] & 0x3; + frame->field_repeat = ptr[4] & 0x10; + + return 0; +} + /** * hdmi_infoframe_unpack() - unpack binary buffer to a HDMI infoframe * @frame: HDMI infoframe @@ -1649,6 +1875,9 @@ int hdmi_infoframe_unpack(union hdmi_infoframe *frame, case HDMI_INFOFRAME_TYPE_VENDOR: ret = hdmi_vendor_any_infoframe_unpack(&frame->vendor, buffer, size); break; + case HDMI_INFOFRAME_TYPE_MPEG_SOURCE: + ret = hdmi_mpeg_source_infoframe_unpack(&frame->mpeg_source, buffer, size); + break; default: ret = -EINVAL; break; diff --git a/include/linux/hdmi.h b/include/linux/hdmi.h index 80521d9591a1..2c9322f7538d 100644 --- a/include/linux/hdmi.h +++ b/include/linux/hdmi.h @@ -47,6 +47,7 @@ enum hdmi_infoframe_type { HDMI_INFOFRAME_TYPE_AVI = 0x82, HDMI_INFOFRAME_TYPE_SPD = 0x83, HDMI_INFOFRAME_TYPE_AUDIO = 0x84, + HDMI_INFOFRAME_TYPE_MPEG_SOURCE = 0x85, }; #define HDMI_IEEE_OUI 0x000c03 @@ -55,6 +56,7 @@ enum hdmi_infoframe_type { #define HDMI_AVI_INFOFRAME_SIZE 13 #define HDMI_SPD_INFOFRAME_SIZE 25 #define HDMI_AUDIO_INFOFRAME_SIZE 10 +#define HDMI_MPEG_SOURCE_INFOFRAME_SIZE 10 #define HDMI_INFOFRAME_SIZE(type) \ (HDMI_INFOFRAME_HEADER_SIZE + HDMI_ ## type ## _INFOFRAME_SIZE) @@ -337,6 +339,29 @@ union hdmi_vendor_any_infoframe { struct hdmi_vendor_infoframe hdmi; }; +enum hdmi_mpeg_frame { + HDMI_MPEG_FRAME_UNKNOWN, + HDMI_MPEG_FRAME_I_PICTURE, + HDMI_MPEG_FRAME_B_PICTURE, + HDMI_MPEG_FRAME_P_PICTURE, +}; + +struct hdmi_mpeg_source_infoframe { + enum hdmi_infoframe_type type; + unsigned char version; + unsigned char length; + unsigned int mpeg_bit_rate; + enum hdmi_mpeg_frame mpeg_frame; + bool field_repeat; +}; + +int hdmi_mpeg_source_infoframe_init(struct hdmi_mpeg_source_infoframe *frame); +ssize_t hdmi_mpeg_source_infoframe_pack(struct hdmi_mpeg_source_infoframe *frame, + void *buffer, size_t size); +ssize_t hdmi_mpeg_source_infoframe_pack_only(const struct hdmi_mpeg_source_infoframe *frame, + void *buffer, size_t size); +int hdmi_mpeg_source_infoframe_check(struct hdmi_mpeg_source_infoframe *frame); + /** * union hdmi_infoframe - overall union of all abstract infoframe representations * @any: generic infoframe @@ -344,6 +369,7 @@ union hdmi_vendor_any_infoframe { * @spd: spd infoframe * @vendor: union of all vendor infoframes * @audio: audio infoframe + * @mpeg_source: mpeg source infoframe * * This is used by the generic pack function. This works since all infoframes * have the same header which also indicates which type of infoframe should be @@ -355,6 +381,7 @@ union hdmi_infoframe { struct hdmi_spd_infoframe spd; union hdmi_vendor_any_infoframe vendor; struct hdmi_audio_infoframe audio; + struct hdmi_mpeg_source_infoframe mpeg_source; }; ssize_t hdmi_infoframe_pack(union hdmi_infoframe *frame, void *buffer, From patchwork Thu Sep 20 18:51:34 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?VmlsbGUgU3lyasOkbMOk?= X-Patchwork-Id: 10608573 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 2C00C5A4 for ; Thu, 20 Sep 2018 18:52:31 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 196812E23A for ; Thu, 20 Sep 2018 18:52:31 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 0D3AE2E259; Thu, 20 Sep 2018 18:52:31 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E9F7E2E2FE for ; Thu, 20 Sep 2018 18:52:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2388197AbeIUAhG (ORCPT ); Thu, 20 Sep 2018 20:37:06 -0400 Received: from mga03.intel.com ([134.134.136.65]:25854 "EHLO mga03.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727171AbeIUAhG (ORCPT ); Thu, 20 Sep 2018 20:37:06 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga103.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 20 Sep 2018 11:52:14 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.54,281,1534834800"; d="scan'208";a="75986573" Received: from stinkbox.fi.intel.com (HELO stinkbox) ([10.237.72.174]) by orsmga006.jf.intel.com with SMTP; 20 Sep 2018 11:52:12 -0700 Received: by stinkbox (sSMTP sendmail emulation); Thu, 20 Sep 2018 21:52:11 +0300 From: Ville Syrjala To: dri-devel@lists.freedesktop.org Cc: intel-gfx@lists.freedesktop.org, Thierry Reding , Hans Verkuil , linux-media@vger.kernel.org Subject: [PATCH 07/18] video/hdmi: Handle the NTSC VBI infoframe Date: Thu, 20 Sep 2018 21:51:34 +0300 Message-Id: <20180920185145.1912-8-ville.syrjala@linux.intel.com> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20180920185145.1912-1-ville.syrjala@linux.intel.com> References: <20180920185145.1912-1-ville.syrjala@linux.intel.com> MIME-Version: 1.0 Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Ville Syrjälä Add the code to deal with the NTSC VBI infoframe. I decided against parsing the PES_data_field and just leave it as an opaque blob, just dumping it out as hex in the log. Blindly typed from the spec, and totally untested. Cc: Thierry Reding Cc: Hans Verkuil Cc: linux-media@vger.kernel.org Signed-off-by: Ville Syrjälä --- drivers/video/hdmi.c | 208 +++++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/hdmi.h | 18 +++++ 2 files changed, 226 insertions(+) diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c index 3d24c7746c51..3c320d69fa0a 100644 --- a/drivers/video/hdmi.c +++ b/drivers/video/hdmi.c @@ -831,6 +831,139 @@ ssize_t hdmi_mpeg_source_infoframe_pack(struct hdmi_mpeg_source_infoframe *frame } EXPORT_SYMBOL(hdmi_mpeg_source_infoframe_pack); +/** + * hdmi_ntsc_vbi_infoframe_init() - initialize an HDMI NTSC VBI infoframe + * @frame: HDMI NTSC VBI infoframe + * @pes_data_field: ANSI/SCTE 127 PES_data_field + * @length: ANSI/SCTE 127 PES_data_field length + * + * Returns 0 on success or a negative error code on failure. + */ +int hdmi_ntsc_vbi_infoframe_init(struct hdmi_ntsc_vbi_infoframe *frame, + const void *pes_data_field, + size_t length) +{ + if (length < 1 || length > 27) + return -EINVAL; + + memset(frame, 0, sizeof(*frame)); + + frame->type = HDMI_INFOFRAME_TYPE_NTSC_VBI; + frame->version = 1; + frame->length = length; + + memcpy(frame->pes_data_field, pes_data_field, length); + + return 0; +} +EXPORT_SYMBOL(hdmi_ntsc_vbi_infoframe_init); + +static int hdmi_ntsc_vbi_infoframe_check_only(const struct hdmi_ntsc_vbi_infoframe *frame) +{ + if (frame->type != HDMI_INFOFRAME_TYPE_NTSC_VBI || + frame->version != 1 || + frame->length < 1 || frame->length > 27) + return -EINVAL; + + if (frame->pes_data_field[0] != 0x99) + return -EINVAL; + + return 0; +} + +/** + * hdmi_ntsc_vbi_infoframe_check() - Check and check a HDMI NTSC VBI infoframe + * @frame: HDMI NTSC VBI infoframe + * + * Validates that the infoframe is consistent and updates derived fields + * (eg. length) based on other fields. + * + * Returns 0 on success or a negative error code on failure. + */ +int hdmi_ntsc_vbi_infoframe_check(struct hdmi_ntsc_vbi_infoframe *frame) +{ + return hdmi_ntsc_vbi_infoframe_check_only(frame); +} +EXPORT_SYMBOL(hdmi_ntsc_vbi_infoframe_check); + +/** + * hdmi_ntsc_vbi_infoframe_pack_only() - write HDMI NTSC VBI infoframe to binary buffer + * @frame: HDMI NTSC VBI infoframe + * @buffer: destination buffer + * @size: size of buffer + * + * Packs the information contained in the @frame structure into a binary + * representation that can be written into the corresponding controller + * registers. Also computes the checksum as required by section 5.3.5 of + * the HDMI 1.4 specification. + * + * Returns the number of bytes packed into the binary buffer or a negative + * error code on failure. + */ +ssize_t hdmi_ntsc_vbi_infoframe_pack_only(const struct hdmi_ntsc_vbi_infoframe *frame, + void *buffer, size_t size) +{ + u8 *ptr = buffer; + size_t length; + int ret; + + ret = hdmi_ntsc_vbi_infoframe_check_only(frame); + if (ret) + return ret; + + length = HDMI_INFOFRAME_HEADER_SIZE + frame->length; + + if (size < length) + return -ENOSPC; + + memset(buffer, 0, size); + + ptr[0] = frame->type; + ptr[1] = frame->version; + ptr[2] = frame->length; + ptr[3] = 0; /* checksum */ + + /* start infoframe payload */ + ptr += HDMI_INFOFRAME_HEADER_SIZE; + + memcpy(ptr, frame->pes_data_field, frame->length); + + hdmi_infoframe_set_checksum(buffer, length); + + return length; +} +EXPORT_SYMBOL(hdmi_ntsc_vbi_infoframe_pack_only); + +/** + * hdmi_ntsc_vbi_infoframe_pack() - Check and check a HDMI NTSC VBI infoframe, + * and write it to binary buffer + * @frame: HDMI NTSC VBI infoframe + * @buffer: destination buffer + * @size: size of buffer + * + * Validates that the infoframe is consistent and updates derived fields + * (eg. length) based on other fields, after which packs the information + * contained in the @frame structure into a binary representation that + * can be written into the corresponding controller registers. Also + * computes the checksum as required by section 5.3.5 of the HDMI 1.4 + * specification. + * + * Returns the number of bytes packed into the binary buffer or a negative + * error code on failure. + */ +ssize_t hdmi_ntsc_vbi_infoframe_pack(struct hdmi_ntsc_vbi_infoframe *frame, + void *buffer, size_t size) +{ + int ret; + + ret = hdmi_ntsc_vbi_infoframe_check(frame); + if (ret) + return ret; + + return hdmi_ntsc_vbi_infoframe_pack_only(frame, buffer, size); +} +EXPORT_SYMBOL(hdmi_ntsc_vbi_infoframe_pack); + /** * hdmi_infoframe_check() - Check check a HDMI infoframe * @frame: HDMI infoframe @@ -854,6 +987,8 @@ hdmi_infoframe_check(union hdmi_infoframe *frame) return hdmi_vendor_any_infoframe_check(&frame->vendor); case HDMI_INFOFRAME_TYPE_MPEG_SOURCE: return hdmi_mpeg_source_infoframe_check(&frame->mpeg_source); + case HDMI_INFOFRAME_TYPE_NTSC_VBI: + return hdmi_ntsc_vbi_infoframe_check(&frame->ntsc_vbi); default: WARN(1, "Bad infoframe type %d\n", frame->any.type); return -EINVAL; @@ -901,6 +1036,10 @@ hdmi_infoframe_pack_only(const union hdmi_infoframe *frame, void *buffer, size_t length = hdmi_mpeg_source_infoframe_pack_only(&frame->mpeg_source, buffer, size); break; + case HDMI_INFOFRAME_TYPE_NTSC_VBI: + length = hdmi_ntsc_vbi_infoframe_pack_only(&frame->ntsc_vbi, + buffer, size); + break; default: WARN(1, "Bad infoframe type %d\n", frame->any.type); length = -EINVAL; @@ -951,6 +1090,10 @@ hdmi_infoframe_pack(union hdmi_infoframe *frame, length = hdmi_mpeg_source_infoframe_pack(&frame->mpeg_source, buffer, size); break; + case HDMI_INFOFRAME_TYPE_NTSC_VBI: + length = hdmi_ntsc_vbi_infoframe_pack(&frame->ntsc_vbi, + buffer, size); + break; default: WARN(1, "Bad infoframe type %d\n", frame->any.type); length = -EINVAL; @@ -975,6 +1118,8 @@ static const char *hdmi_infoframe_type_get_name(enum hdmi_infoframe_type type) return "Audio"; case HDMI_INFOFRAME_TYPE_MPEG_SOURCE: return "MPEG Source"; + case HDMI_INFOFRAME_TYPE_NTSC_VBI: + return "NTSC VBI"; } return "Reserved"; } @@ -1526,6 +1671,22 @@ static void hdmi_mpeg_source_infoframe_log(const char *level, frame->field_repeat ? "Yes" : "No"); } +/** + * hdmi_ntsc_vbi_infoframe_log() - log info of HDMI NTSC VBI infoframe + * @level: logging level + * @dev: device + * @frame: HDMI NTSC VBI infoframe + */ +static void hdmi_ntsc_vbi_infoframe_log(const char *level, + struct device *dev, + const struct hdmi_ntsc_vbi_infoframe *frame) +{ + hdmi_infoframe_log_header(level, dev, + (const struct hdmi_any_infoframe *)frame); + + hdmi_log(" %*ph\n", frame->length, frame->pes_data_field); +} + /** * hdmi_infoframe_log() - log info of HDMI infoframe * @level: logging level @@ -1552,6 +1713,9 @@ void hdmi_infoframe_log(const char *level, case HDMI_INFOFRAME_TYPE_MPEG_SOURCE: hdmi_mpeg_source_infoframe_log(level, dev, &frame->mpeg_source); break; + case HDMI_INFOFRAME_TYPE_NTSC_VBI: + hdmi_ntsc_vbi_infoframe_log(level, dev, &frame->ntsc_vbi); + break; } } EXPORT_SYMBOL(hdmi_infoframe_log); @@ -1840,6 +2004,47 @@ static int hdmi_mpeg_source_infoframe_unpack(struct hdmi_mpeg_source_infoframe * return 0; } +/** + * hdmi_ntsc_vbi_infoframe_unpack() - unpack binary buffer to a HDMI MPEG Source infoframe + * @frame: HDMI MPEG Source infoframe + * @buffer: source buffer + * @size: size of buffer + * + * Unpacks the information contained in binary @buffer into a structured + * @frame of the HDMI MPEG Source information frame. + * Also verifies the checksum as required by section 5.3.5 of the HDMI 1.4 + * specification. + * + * Returns 0 on success or a negative error code on failure. + */ +static int hdmi_ntsc_vbi_infoframe_unpack(struct hdmi_ntsc_vbi_infoframe *frame, + const void *buffer, size_t size) +{ + const u8 *ptr = buffer; + size_t length; + + if (size < HDMI_INFOFRAME_HEADER_SIZE) + return -EINVAL; + + if (ptr[0] != HDMI_INFOFRAME_TYPE_NTSC_VBI || + ptr[1] != 1 || + ptr[2] < 1 || ptr[2] > 27) + return -EINVAL; + + length = ptr[2]; + + if (size < HDMI_INFOFRAME_HEADER_SIZE + length) + return -EINVAL; + + if (hdmi_infoframe_checksum(buffer, + HDMI_INFOFRAME_HEADER_SIZE + length) != 0) + return -EINVAL; + + ptr += HDMI_INFOFRAME_HEADER_SIZE; + + return hdmi_ntsc_vbi_infoframe_init(frame, ptr, length); +} + /** * hdmi_infoframe_unpack() - unpack binary buffer to a HDMI infoframe * @frame: HDMI infoframe @@ -1878,6 +2083,9 @@ int hdmi_infoframe_unpack(union hdmi_infoframe *frame, case HDMI_INFOFRAME_TYPE_MPEG_SOURCE: ret = hdmi_mpeg_source_infoframe_unpack(&frame->mpeg_source, buffer, size); break; + case HDMI_INFOFRAME_TYPE_NTSC_VBI: + ret = hdmi_ntsc_vbi_infoframe_unpack(&frame->ntsc_vbi, buffer, size); + break; default: ret = -EINVAL; break; diff --git a/include/linux/hdmi.h b/include/linux/hdmi.h index 2c9322f7538d..3821516b336c 100644 --- a/include/linux/hdmi.h +++ b/include/linux/hdmi.h @@ -48,6 +48,7 @@ enum hdmi_infoframe_type { HDMI_INFOFRAME_TYPE_SPD = 0x83, HDMI_INFOFRAME_TYPE_AUDIO = 0x84, HDMI_INFOFRAME_TYPE_MPEG_SOURCE = 0x85, + HDMI_INFOFRAME_TYPE_NTSC_VBI = 0x86, }; #define HDMI_IEEE_OUI 0x000c03 @@ -362,6 +363,21 @@ ssize_t hdmi_mpeg_source_infoframe_pack_only(const struct hdmi_mpeg_source_infof void *buffer, size_t size); int hdmi_mpeg_source_infoframe_check(struct hdmi_mpeg_source_infoframe *frame); +struct hdmi_ntsc_vbi_infoframe { + enum hdmi_infoframe_type type; + unsigned char version; + unsigned char length; + unsigned char pes_data_field[27]; +}; + +int hdmi_ntsc_vbi_infoframe_init(struct hdmi_ntsc_vbi_infoframe *frame, + const void *pes_data_field, size_t length); +ssize_t hdmi_ntsc_vbi_infoframe_pack(struct hdmi_ntsc_vbi_infoframe *frame, + void *buffer, size_t size); +ssize_t hdmi_ntsc_vbi_infoframe_pack_only(const struct hdmi_ntsc_vbi_infoframe *frame, + void *buffer, size_t size); +int hdmi_ntsc_vbi_infoframe_check(struct hdmi_ntsc_vbi_infoframe *frame); + /** * union hdmi_infoframe - overall union of all abstract infoframe representations * @any: generic infoframe @@ -370,6 +386,7 @@ int hdmi_mpeg_source_infoframe_check(struct hdmi_mpeg_source_infoframe *frame); * @vendor: union of all vendor infoframes * @audio: audio infoframe * @mpeg_source: mpeg source infoframe + * @ntsc_vbi: ntsc vbi infoframe * * This is used by the generic pack function. This works since all infoframes * have the same header which also indicates which type of infoframe should be @@ -382,6 +399,7 @@ union hdmi_infoframe { union hdmi_vendor_any_infoframe vendor; struct hdmi_audio_infoframe audio; struct hdmi_mpeg_source_infoframe mpeg_source; + struct hdmi_ntsc_vbi_infoframe ntsc_vbi; }; ssize_t hdmi_infoframe_pack(union hdmi_infoframe *frame, void *buffer,