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