brintos

brintos / linux-shallow public Read only

0
0
Text · 19.0 KiB · 35bdb53 Raw
614 lines · c
1// SPDX-License-Identifier: MIT2/*3 * Copyright 2023, Intel Corporation.4 */5 6#include <linux/err.h>7#include <drm/intel/i915_hdcp_interface.h>8 9#include "i915_drv.h"10#include "intel_display_types.h"11#include "intel_hdcp_gsc_message.h"12 13int14intel_hdcp_gsc_initiate_session(struct device *dev, struct hdcp_port_data *data,15				struct hdcp2_ake_init *ake_data)16{17	struct wired_cmd_initiate_hdcp2_session_in session_init_in = {};18	struct wired_cmd_initiate_hdcp2_session_out session_init_out = {};19	struct intel_display *display;20	struct drm_i915_private *i915;21	ssize_t byte;22 23	if (!dev || !data || !ake_data)24		return -EINVAL;25 26	display = to_intel_display(dev);27	if (!display) {28		dev_err(dev, "DRM not initialized, aborting HDCP.\n");29		return -ENODEV;30	}31	i915 = to_i915(display->drm);32 33	session_init_in.header.api_version = HDCP_API_VERSION;34	session_init_in.header.command_id = WIRED_INITIATE_HDCP2_SESSION;35	session_init_in.header.status = FW_HDCP_STATUS_SUCCESS;36	session_init_in.header.buffer_len =37				WIRED_CMD_BUF_LEN_INITIATE_HDCP2_SESSION_IN;38 39	session_init_in.port.integrated_port_type = data->port_type;40	session_init_in.port.physical_port = (u8)data->hdcp_ddi;41	session_init_in.port.attached_transcoder = (u8)data->hdcp_transcoder;42	session_init_in.protocol = data->protocol;43 44	byte = intel_hdcp_gsc_msg_send(i915, (u8 *)&session_init_in,45				       sizeof(session_init_in),46				       (u8 *)&session_init_out,47				       sizeof(session_init_out));48	if (byte < 0) {49		drm_dbg_kms(&i915->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte);50		return byte;51	}52 53	if (session_init_out.header.status != FW_HDCP_STATUS_SUCCESS) {54		drm_dbg_kms(&i915->drm, "FW cmd 0x%08X Failed. Status: 0x%X\n",55			    WIRED_INITIATE_HDCP2_SESSION,56			    session_init_out.header.status);57		return -EIO;58	}59 60	ake_data->msg_id = HDCP_2_2_AKE_INIT;61	ake_data->tx_caps = session_init_out.tx_caps;62	memcpy(ake_data->r_tx, session_init_out.r_tx, HDCP_2_2_RTX_LEN);63 64	return 0;65}66 67int68intel_hdcp_gsc_verify_receiver_cert_prepare_km(struct device *dev,69					       struct hdcp_port_data *data,70					       struct hdcp2_ake_send_cert *rx_cert,71					       bool *km_stored,72					       struct hdcp2_ake_no_stored_km73					       *ek_pub_km,74					       size_t *msg_sz)75{76	struct wired_cmd_verify_receiver_cert_in verify_rxcert_in = {};77	struct wired_cmd_verify_receiver_cert_out verify_rxcert_out = {};78	struct intel_display *display;79	struct drm_i915_private *i915;80	ssize_t byte;81 82	if (!dev || !data || !rx_cert || !km_stored || !ek_pub_km || !msg_sz)83		return -EINVAL;84 85	display = to_intel_display(dev);86	if (!display) {87		dev_err(dev, "DRM not initialized, aborting HDCP.\n");88		return -ENODEV;89	}90	i915 = to_i915(display->drm);91 92	verify_rxcert_in.header.api_version = HDCP_API_VERSION;93	verify_rxcert_in.header.command_id = WIRED_VERIFY_RECEIVER_CERT;94	verify_rxcert_in.header.status = FW_HDCP_STATUS_SUCCESS;95	verify_rxcert_in.header.buffer_len =96				WIRED_CMD_BUF_LEN_VERIFY_RECEIVER_CERT_IN;97 98	verify_rxcert_in.port.integrated_port_type = data->port_type;99	verify_rxcert_in.port.physical_port = (u8)data->hdcp_ddi;100	verify_rxcert_in.port.attached_transcoder = (u8)data->hdcp_transcoder;101 102	verify_rxcert_in.cert_rx = rx_cert->cert_rx;103	memcpy(verify_rxcert_in.r_rx, &rx_cert->r_rx, HDCP_2_2_RRX_LEN);104	memcpy(verify_rxcert_in.rx_caps, rx_cert->rx_caps, HDCP_2_2_RXCAPS_LEN);105 106	byte = intel_hdcp_gsc_msg_send(i915, (u8 *)&verify_rxcert_in,107				       sizeof(verify_rxcert_in),108				       (u8 *)&verify_rxcert_out,109				       sizeof(verify_rxcert_out));110	if (byte < 0) {111		drm_dbg_kms(&i915->drm, "intel_hdcp_gsc_msg_send failed: %zd\n", byte);112		return byte;113	}114 115	if (verify_rxcert_out.header.status != FW_HDCP_STATUS_SUCCESS) {116		drm_dbg_kms(&i915->drm, "FW cmd 0x%08X Failed. Status: 0x%X\n",117			    WIRED_VERIFY_RECEIVER_CERT,118			    verify_rxcert_out.header.status);119		return -EIO;120	}121 122	*km_stored = !!verify_rxcert_out.km_stored;123	if (verify_rxcert_out.km_stored) {124		ek_pub_km->msg_id = HDCP_2_2_AKE_STORED_KM;125		*msg_sz = sizeof(struct hdcp2_ake_stored_km);126	} else {127		ek_pub_km->msg_id = HDCP_2_2_AKE_NO_STORED_KM;128		*msg_sz = sizeof(struct hdcp2_ake_no_stored_km);129	}130 131	memcpy(ek_pub_km->e_kpub_km, &verify_rxcert_out.ekm_buff,132	       sizeof(verify_rxcert_out.ekm_buff));133 134	return 0;135}136 137int138intel_hdcp_gsc_verify_hprime(struct device *dev, struct hdcp_port_data *data,139			     struct hdcp2_ake_send_hprime *rx_hprime)140{141	struct wired_cmd_ake_send_hprime_in send_hprime_in = {};142	struct wired_cmd_ake_send_hprime_out send_hprime_out = {};143	struct intel_display *display;144	struct drm_i915_private *i915;145	ssize_t byte;146 147	if (!dev || !data || !rx_hprime)148		return -EINVAL;149 150	display = to_intel_display(dev);151	if (!display) {152		dev_err(dev, "DRM not initialized, aborting HDCP.\n");153		return -ENODEV;154	}155	i915 = to_i915(display->drm);156 157	send_hprime_in.header.api_version = HDCP_API_VERSION;158	send_hprime_in.header.command_id = WIRED_AKE_SEND_HPRIME;159	send_hprime_in.header.status = FW_HDCP_STATUS_SUCCESS;160	send_hprime_in.header.buffer_len = WIRED_CMD_BUF_LEN_AKE_SEND_HPRIME_IN;161 162	send_hprime_in.port.integrated_port_type = data->port_type;163	send_hprime_in.port.physical_port = (u8)data->hdcp_ddi;164	send_hprime_in.port.attached_transcoder = (u8)data->hdcp_transcoder;165 166	memcpy(send_hprime_in.h_prime, rx_hprime->h_prime,167	       HDCP_2_2_H_PRIME_LEN);168 169	byte = intel_hdcp_gsc_msg_send(i915, (u8 *)&send_hprime_in,170				       sizeof(send_hprime_in),171				       (u8 *)&send_hprime_out,172				       sizeof(send_hprime_out));173	if (byte < 0) {174		drm_dbg_kms(&i915->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte);175		return byte;176	}177 178	if (send_hprime_out.header.status != FW_HDCP_STATUS_SUCCESS) {179		drm_dbg_kms(&i915->drm, "FW cmd 0x%08X Failed. Status: 0x%X\n",180			    WIRED_AKE_SEND_HPRIME, send_hprime_out.header.status);181		return -EIO;182	}183 184	return 0;185}186 187int188intel_hdcp_gsc_store_pairing_info(struct device *dev, struct hdcp_port_data *data,189				  struct hdcp2_ake_send_pairing_info *pairing_info)190{191	struct wired_cmd_ake_send_pairing_info_in pairing_info_in = {};192	struct wired_cmd_ake_send_pairing_info_out pairing_info_out = {};193	struct intel_display *display;194	struct drm_i915_private *i915;195	ssize_t byte;196 197	if (!dev || !data || !pairing_info)198		return -EINVAL;199 200	display = to_intel_display(dev);201	if (!display) {202		dev_err(dev, "DRM not initialized, aborting HDCP.\n");203		return -ENODEV;204	}205	i915 = to_i915(display->drm);206 207	pairing_info_in.header.api_version = HDCP_API_VERSION;208	pairing_info_in.header.command_id = WIRED_AKE_SEND_PAIRING_INFO;209	pairing_info_in.header.status = FW_HDCP_STATUS_SUCCESS;210	pairing_info_in.header.buffer_len =211					WIRED_CMD_BUF_LEN_SEND_PAIRING_INFO_IN;212 213	pairing_info_in.port.integrated_port_type = data->port_type;214	pairing_info_in.port.physical_port = (u8)data->hdcp_ddi;215	pairing_info_in.port.attached_transcoder = (u8)data->hdcp_transcoder;216 217	memcpy(pairing_info_in.e_kh_km, pairing_info->e_kh_km,218	       HDCP_2_2_E_KH_KM_LEN);219 220	byte = intel_hdcp_gsc_msg_send(i915, (u8 *)&pairing_info_in,221				       sizeof(pairing_info_in),222				       (u8 *)&pairing_info_out,223				       sizeof(pairing_info_out));224	if (byte < 0) {225		drm_dbg_kms(&i915->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte);226		return byte;227	}228 229	if (pairing_info_out.header.status != FW_HDCP_STATUS_SUCCESS) {230		drm_dbg_kms(&i915->drm, "FW cmd 0x%08X failed. Status: 0x%X\n",231			    WIRED_AKE_SEND_PAIRING_INFO,232			    pairing_info_out.header.status);233		return -EIO;234	}235 236	return 0;237}238 239int240intel_hdcp_gsc_initiate_locality_check(struct device *dev,241				       struct hdcp_port_data *data,242				       struct hdcp2_lc_init *lc_init_data)243{244	struct wired_cmd_init_locality_check_in lc_init_in = {};245	struct wired_cmd_init_locality_check_out lc_init_out = {};246	struct intel_display *display;247	struct drm_i915_private *i915;248	ssize_t byte;249 250	if (!dev || !data || !lc_init_data)251		return -EINVAL;252 253	display = to_intel_display(dev);254	if (!display) {255		dev_err(dev, "DRM not initialized, aborting HDCP.\n");256		return -ENODEV;257	}258	i915 = to_i915(display->drm);259 260	lc_init_in.header.api_version = HDCP_API_VERSION;261	lc_init_in.header.command_id = WIRED_INIT_LOCALITY_CHECK;262	lc_init_in.header.status = FW_HDCP_STATUS_SUCCESS;263	lc_init_in.header.buffer_len = WIRED_CMD_BUF_LEN_INIT_LOCALITY_CHECK_IN;264 265	lc_init_in.port.integrated_port_type = data->port_type;266	lc_init_in.port.physical_port = (u8)data->hdcp_ddi;267	lc_init_in.port.attached_transcoder = (u8)data->hdcp_transcoder;268 269	byte = intel_hdcp_gsc_msg_send(i915, (u8 *)&lc_init_in, sizeof(lc_init_in),270				       (u8 *)&lc_init_out, sizeof(lc_init_out));271	if (byte < 0) {272		drm_dbg_kms(&i915->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte);273		return byte;274	}275 276	if (lc_init_out.header.status != FW_HDCP_STATUS_SUCCESS) {277		drm_dbg_kms(&i915->drm, "FW cmd 0x%08X Failed. status: 0x%X\n",278			    WIRED_INIT_LOCALITY_CHECK, lc_init_out.header.status);279		return -EIO;280	}281 282	lc_init_data->msg_id = HDCP_2_2_LC_INIT;283	memcpy(lc_init_data->r_n, lc_init_out.r_n, HDCP_2_2_RN_LEN);284 285	return 0;286}287 288int289intel_hdcp_gsc_verify_lprime(struct device *dev, struct hdcp_port_data *data,290			     struct hdcp2_lc_send_lprime *rx_lprime)291{292	struct wired_cmd_validate_locality_in verify_lprime_in = {};293	struct wired_cmd_validate_locality_out verify_lprime_out = {};294	struct intel_display *display;295	struct drm_i915_private *i915;296	ssize_t byte;297 298	if (!dev || !data || !rx_lprime)299		return -EINVAL;300 301	display = to_intel_display(dev);302	if (!display) {303		dev_err(dev, "DRM not initialized, aborting HDCP.\n");304		return -ENODEV;305	}306	i915 = to_i915(display->drm);307 308	verify_lprime_in.header.api_version = HDCP_API_VERSION;309	verify_lprime_in.header.command_id = WIRED_VALIDATE_LOCALITY;310	verify_lprime_in.header.status = FW_HDCP_STATUS_SUCCESS;311	verify_lprime_in.header.buffer_len =312					WIRED_CMD_BUF_LEN_VALIDATE_LOCALITY_IN;313 314	verify_lprime_in.port.integrated_port_type = data->port_type;315	verify_lprime_in.port.physical_port = (u8)data->hdcp_ddi;316	verify_lprime_in.port.attached_transcoder = (u8)data->hdcp_transcoder;317 318	memcpy(verify_lprime_in.l_prime, rx_lprime->l_prime,319	       HDCP_2_2_L_PRIME_LEN);320 321	byte = intel_hdcp_gsc_msg_send(i915, (u8 *)&verify_lprime_in,322				       sizeof(verify_lprime_in),323				       (u8 *)&verify_lprime_out,324				       sizeof(verify_lprime_out));325	if (byte < 0) {326		drm_dbg_kms(&i915->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte);327		return byte;328	}329 330	if (verify_lprime_out.header.status != FW_HDCP_STATUS_SUCCESS) {331		drm_dbg_kms(&i915->drm, "FW cmd 0x%08X failed. status: 0x%X\n",332			    WIRED_VALIDATE_LOCALITY,333			    verify_lprime_out.header.status);334		return -EIO;335	}336 337	return 0;338}339 340int intel_hdcp_gsc_get_session_key(struct device *dev,341				   struct hdcp_port_data *data,342				   struct hdcp2_ske_send_eks *ske_data)343{344	struct wired_cmd_get_session_key_in get_skey_in = {};345	struct wired_cmd_get_session_key_out get_skey_out = {};346	struct intel_display *display;347	struct drm_i915_private *i915;348	ssize_t byte;349 350	if (!dev || !data || !ske_data)351		return -EINVAL;352 353	display = to_intel_display(dev);354	if (!display) {355		dev_err(dev, "DRM not initialized, aborting HDCP.\n");356		return -ENODEV;357	}358	i915 = to_i915(display->drm);359 360	get_skey_in.header.api_version = HDCP_API_VERSION;361	get_skey_in.header.command_id = WIRED_GET_SESSION_KEY;362	get_skey_in.header.status = FW_HDCP_STATUS_SUCCESS;363	get_skey_in.header.buffer_len = WIRED_CMD_BUF_LEN_GET_SESSION_KEY_IN;364 365	get_skey_in.port.integrated_port_type = data->port_type;366	get_skey_in.port.physical_port = (u8)data->hdcp_ddi;367	get_skey_in.port.attached_transcoder = (u8)data->hdcp_transcoder;368 369	byte = intel_hdcp_gsc_msg_send(i915, (u8 *)&get_skey_in, sizeof(get_skey_in),370				       (u8 *)&get_skey_out, sizeof(get_skey_out));371	if (byte < 0) {372		drm_dbg_kms(&i915->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte);373		return byte;374	}375 376	if (get_skey_out.header.status != FW_HDCP_STATUS_SUCCESS) {377		drm_dbg_kms(&i915->drm, "FW cmd 0x%08X failed. status: 0x%X\n",378			    WIRED_GET_SESSION_KEY, get_skey_out.header.status);379		return -EIO;380	}381 382	ske_data->msg_id = HDCP_2_2_SKE_SEND_EKS;383	memcpy(ske_data->e_dkey_ks, get_skey_out.e_dkey_ks,384	       HDCP_2_2_E_DKEY_KS_LEN);385	memcpy(ske_data->riv, get_skey_out.r_iv, HDCP_2_2_RIV_LEN);386 387	return 0;388}389 390int391intel_hdcp_gsc_repeater_check_flow_prepare_ack(struct device *dev,392					       struct hdcp_port_data *data,393					       struct hdcp2_rep_send_receiverid_list394					       *rep_topology,395					       struct hdcp2_rep_send_ack396					       *rep_send_ack)397{398	struct wired_cmd_verify_repeater_in verify_repeater_in = {};399	struct wired_cmd_verify_repeater_out verify_repeater_out = {};400	struct intel_display *display;401	struct drm_i915_private *i915;402	ssize_t byte;403 404	if (!dev || !rep_topology || !rep_send_ack || !data)405		return -EINVAL;406 407	display = to_intel_display(dev);408	if (!display) {409		dev_err(dev, "DRM not initialized, aborting HDCP.\n");410		return -ENODEV;411	}412	i915 = to_i915(display->drm);413 414	verify_repeater_in.header.api_version = HDCP_API_VERSION;415	verify_repeater_in.header.command_id = WIRED_VERIFY_REPEATER;416	verify_repeater_in.header.status = FW_HDCP_STATUS_SUCCESS;417	verify_repeater_in.header.buffer_len =418					WIRED_CMD_BUF_LEN_VERIFY_REPEATER_IN;419 420	verify_repeater_in.port.integrated_port_type = data->port_type;421	verify_repeater_in.port.physical_port = (u8)data->hdcp_ddi;422	verify_repeater_in.port.attached_transcoder = (u8)data->hdcp_transcoder;423 424	memcpy(verify_repeater_in.rx_info, rep_topology->rx_info,425	       HDCP_2_2_RXINFO_LEN);426	memcpy(verify_repeater_in.seq_num_v, rep_topology->seq_num_v,427	       HDCP_2_2_SEQ_NUM_LEN);428	memcpy(verify_repeater_in.v_prime, rep_topology->v_prime,429	       HDCP_2_2_V_PRIME_HALF_LEN);430	memcpy(verify_repeater_in.receiver_ids, rep_topology->receiver_ids,431	       HDCP_2_2_RECEIVER_IDS_MAX_LEN);432 433	byte = intel_hdcp_gsc_msg_send(i915, (u8 *)&verify_repeater_in,434				       sizeof(verify_repeater_in),435				       (u8 *)&verify_repeater_out,436				       sizeof(verify_repeater_out));437	if (byte < 0) {438		drm_dbg_kms(&i915->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte);439		return byte;440	}441 442	if (verify_repeater_out.header.status != FW_HDCP_STATUS_SUCCESS) {443		drm_dbg_kms(&i915->drm, "FW cmd 0x%08X failed. status: 0x%X\n",444			    WIRED_VERIFY_REPEATER,445			    verify_repeater_out.header.status);446		return -EIO;447	}448 449	memcpy(rep_send_ack->v, verify_repeater_out.v,450	       HDCP_2_2_V_PRIME_HALF_LEN);451	rep_send_ack->msg_id = HDCP_2_2_REP_SEND_ACK;452 453	return 0;454}455 456int intel_hdcp_gsc_verify_mprime(struct device *dev,457				 struct hdcp_port_data *data,458				 struct hdcp2_rep_stream_ready *stream_ready)459{460	struct wired_cmd_repeater_auth_stream_req_in *verify_mprime_in;461	struct wired_cmd_repeater_auth_stream_req_out verify_mprime_out = {};462	struct intel_display *display;463	struct drm_i915_private *i915;464	ssize_t byte;465	size_t cmd_size;466 467	if (!dev || !stream_ready || !data)468		return -EINVAL;469 470	display = to_intel_display(dev);471	if (!display) {472		dev_err(dev, "DRM not initialized, aborting HDCP.\n");473		return -ENODEV;474	}475	i915 = to_i915(display->drm);476 477	cmd_size = struct_size(verify_mprime_in, streams, data->k);478	if (cmd_size == SIZE_MAX)479		return -EINVAL;480 481	verify_mprime_in = kzalloc(cmd_size, GFP_KERNEL);482	if (!verify_mprime_in)483		return -ENOMEM;484 485	verify_mprime_in->header.api_version = HDCP_API_VERSION;486	verify_mprime_in->header.command_id = WIRED_REPEATER_AUTH_STREAM_REQ;487	verify_mprime_in->header.status = FW_HDCP_STATUS_SUCCESS;488	verify_mprime_in->header.buffer_len = cmd_size  - sizeof(verify_mprime_in->header);489 490	verify_mprime_in->port.integrated_port_type = data->port_type;491	verify_mprime_in->port.physical_port = (u8)data->hdcp_ddi;492	verify_mprime_in->port.attached_transcoder = (u8)data->hdcp_transcoder;493 494	memcpy(verify_mprime_in->m_prime, stream_ready->m_prime, HDCP_2_2_MPRIME_LEN);495	drm_hdcp_cpu_to_be24(verify_mprime_in->seq_num_m, data->seq_num_m);496 497	memcpy(verify_mprime_in->streams, data->streams,498	       array_size(data->k, sizeof(*data->streams)));499 500	verify_mprime_in->k = cpu_to_be16(data->k);501 502	byte = intel_hdcp_gsc_msg_send(i915, (u8 *)verify_mprime_in, cmd_size,503				       (u8 *)&verify_mprime_out,504				       sizeof(verify_mprime_out));505	kfree(verify_mprime_in);506	if (byte < 0) {507		drm_dbg_kms(&i915->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte);508		return byte;509	}510 511	if (verify_mprime_out.header.status != FW_HDCP_STATUS_SUCCESS) {512		drm_dbg_kms(&i915->drm, "FW cmd 0x%08X failed. status: 0x%X\n",513			    WIRED_REPEATER_AUTH_STREAM_REQ,514			    verify_mprime_out.header.status);515		return -EIO;516	}517 518	return 0;519}520 521int intel_hdcp_gsc_enable_authentication(struct device *dev,522					 struct hdcp_port_data *data)523{524	struct wired_cmd_enable_auth_in enable_auth_in = {};525	struct wired_cmd_enable_auth_out enable_auth_out = {};526	struct intel_display *display;527	struct drm_i915_private *i915;528	ssize_t byte;529 530	if (!dev || !data)531		return -EINVAL;532 533	display = to_intel_display(dev);534	if (!display) {535		dev_err(dev, "DRM not initialized, aborting HDCP.\n");536		return -ENODEV;537	}538	i915 = to_i915(display->drm);539 540	enable_auth_in.header.api_version = HDCP_API_VERSION;541	enable_auth_in.header.command_id = WIRED_ENABLE_AUTH;542	enable_auth_in.header.status = FW_HDCP_STATUS_SUCCESS;543	enable_auth_in.header.buffer_len = WIRED_CMD_BUF_LEN_ENABLE_AUTH_IN;544 545	enable_auth_in.port.integrated_port_type = data->port_type;546	enable_auth_in.port.physical_port = (u8)data->hdcp_ddi;547	enable_auth_in.port.attached_transcoder = (u8)data->hdcp_transcoder;548	enable_auth_in.stream_type = data->streams[0].stream_type;549 550	byte = intel_hdcp_gsc_msg_send(i915, (u8 *)&enable_auth_in,551				       sizeof(enable_auth_in),552				       (u8 *)&enable_auth_out,553				       sizeof(enable_auth_out));554	if (byte < 0) {555		drm_dbg_kms(&i915->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte);556		return byte;557	}558 559	if (enable_auth_out.header.status != FW_HDCP_STATUS_SUCCESS) {560		drm_dbg_kms(&i915->drm, "FW cmd 0x%08X failed. status: 0x%X\n",561			    WIRED_ENABLE_AUTH, enable_auth_out.header.status);562		return -EIO;563	}564 565	return 0;566}567 568int569intel_hdcp_gsc_close_session(struct device *dev, struct hdcp_port_data *data)570{571	struct wired_cmd_close_session_in session_close_in = {};572	struct wired_cmd_close_session_out session_close_out = {};573	struct intel_display *display;574	struct drm_i915_private *i915;575	ssize_t byte;576 577	if (!dev || !data)578		return -EINVAL;579 580	display = to_intel_display(dev);581	if (!display) {582		dev_err(dev, "DRM not initialized, aborting HDCP.\n");583		return -ENODEV;584	}585	i915 = to_i915(display->drm);586 587	session_close_in.header.api_version = HDCP_API_VERSION;588	session_close_in.header.command_id = WIRED_CLOSE_SESSION;589	session_close_in.header.status = FW_HDCP_STATUS_SUCCESS;590	session_close_in.header.buffer_len =591				WIRED_CMD_BUF_LEN_CLOSE_SESSION_IN;592 593	session_close_in.port.integrated_port_type = data->port_type;594	session_close_in.port.physical_port = (u8)data->hdcp_ddi;595	session_close_in.port.attached_transcoder = (u8)data->hdcp_transcoder;596 597	byte = intel_hdcp_gsc_msg_send(i915, (u8 *)&session_close_in,598				       sizeof(session_close_in),599				       (u8 *)&session_close_out,600				       sizeof(session_close_out));601	if (byte < 0) {602		drm_dbg_kms(&i915->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte);603		return byte;604	}605 606	if (session_close_out.header.status != FW_HDCP_STATUS_SUCCESS) {607		drm_dbg_kms(&i915->drm, "Session Close Failed. status: 0x%X\n",608			    session_close_out.header.status);609		return -EIO;610	}611 612	return 0;613}614