Patch "drm/dp/mst: process broadcast messages correctly" has been added to the 4.4-stable tree
Subsystems (3)
This is a note to let you know that I've just added the patch titled
drm/dp/mst: process broadcast messages correctly
to the 4.4-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
drm-dp-mst-process-broadcast-messages-correctly.patch
and it can be found in the queue-4.4 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
bd9343208704fcc70a5b919f228a7d26ae472727Mon Sep 17 00:00:00 2001
From: Mykola Lysenko <[email protected]>
Date: Fri, 18 Dec 2015 17:14:42 -0500
Subject: drm/dp/mst: process broadcast messages correctly
From: Mykola Lysenko <[email protected]>
commit bd9343208704fcc70a5b919f228a7d26ae472727 upstream.
In case broadcast message received in UP request, RAD cannot be used to identify message originator. Message should be parsed, originator should be found by GUID from parsed message.
Also reply with broadcast in case broadcast message received (for now it is always broadcast)
--- drivers/gpu/drm/drm_dp_mst_topology.c | 95 ++++++++++++++++++++++++++++++---- 1 file changed, 84 insertions(+), 11 deletions(-)
drivers/gpu/drm/drm_dp_mst_topology.c +84 -11
@@ -1210,6 +1210,50 @@ out:return mstb; } +static struct drm_dp_mst_branch *get_mst_branch_device_by_guid_helper ( +struct drm_dp_mst_branch *mstb, +uint8_t *guid) +{ +struct drm_dp_mst_branch *found_mstb; +struct drm_dp_mst_port *port; + +list_for_each_entry (port, &mstb->ports, next) { +if (!port->mstb) +continue ; + +if (port->guid_valid &&memcmp (port->guid, guid,16 ) ==0 ) +return port->mstb; + + found_mstb =get_mst_branch_device_by_guid_helper (port->mstb, guid); + +if (found_mstb) +return found_mstb; + } + +return NULL ; +} + +static struct drm_dp_mst_branch *drm_dp_get_mst_branch_device_by_guid ( +struct drm_dp_mst_topology_mgr *mgr, +uint8_t *guid) +{ +struct drm_dp_mst_branch *mstb; + +/* find the port by iterating down */ +mutex_lock (&mgr->lock); + +if (mgr->guid_valid &&memcmp (mgr->guid, guid,16 ) ==0 ) + mstb = mgr->mst_primary; +else + mstb =get_mst_branch_device_by_guid_helper (mgr->mst_primary, guid); + +if (mstb) +kref_get (&mstb->kref); + +mutex_unlock (&mgr->lock); +return mstb; +} +static void drm_dp_check_and_send_link_address (struct drm_dp_mst_topology_mgr *mgr,struct drm_dp_mst_branch *mstb) {
@@ -1320,6 +1364,7 @@ static int set_hdr_from_dst_qlock(struct struct drm_dp_sideband_msg_tx *txmsg) {struct drm_dp_mst_branch *mstb = txmsg->dst; +u8 req_type;/* both msg slots are full */ if (txmsg->seqno ==-1 ) {
@@ -1336,7 +1381,13 @@ static int set_hdr_from_dst_qlock(struct txmsg->seqno =1 ; mstb->tx_slots[txmsg->seqno] = txmsg; } - hdr->broadcast =0 ; + + req_type = txmsg->msg[0 ] &0x7f ; +if (req_type ==DP_CONNECTION_STATUS_NOTIFY || + req_type ==DP_RESOURCE_STATUS_NOTIFY ) + hdr->broadcast =1 ; +else + hdr->broadcast =0 ; hdr->path_msg = txmsg->path_msg; hdr->lct = mstb->lct; hdr->lcr = mstb->lct -1 ;
@@ -2145,28 +2196,50 @@ static int drm_dp_mst_handle_up_req(struif (mgr->up_req_recv.have_eomt) {struct drm_dp_sideband_msg_req_body msg; -struct drm_dp_mst_branch *mstb; +struct drm_dp_mst_branch *mstb =NULL ;bool seqno; - mstb =drm_dp_get_mst_branch_device (mgr, - mgr->up_req_recv.initial_hdr.lct, - mgr->up_req_recv.initial_hdr.rad); -if (!mstb) { -DRM_DEBUG_KMS ("Got MST reply from unknown device %d\n" , mgr->up_req_recv.initial_hdr.lct); -memset (&mgr->up_req_recv,0 ,sizeof (struct drm_dp_sideband_msg_rx )); -return 0 ; + +if (!mgr->up_req_recv.initial_hdr.broadcast) { + mstb =drm_dp_get_mst_branch_device (mgr, + mgr->up_req_recv.initial_hdr.lct, + mgr->up_req_recv.initial_hdr.rad); +if (!mstb) { +DRM_DEBUG_KMS ("Got MST reply from unknown device %d\n" , mgr->up_req_recv.initial_hdr.lct); +memset (&mgr->up_req_recv,0 ,sizeof (struct drm_dp_sideband_msg_rx )); +return 0 ; + } } seqno = mgr->up_req_recv.initial_hdr.seqno;drm_dp_sideband_parse_req (&mgr->up_req_recv, &msg);if (msg.req_type ==DP_CONNECTION_STATUS_NOTIFY ) { -drm_dp_send_up_ack_reply (mgr, mstb, msg.req_type, seqno, false); +drm_dp_send_up_ack_reply (mgr, mgr->mst_primary, msg.req_type, seqno, false); + +if (!mstb) + mstb =drm_dp_get_mst_branch_device_by_guid (mgr, msg.u.conn_stat.guid); + +if (!mstb) { +DRM_DEBUG_KMS ("Got MST reply from unknown device %d\n" , mgr->up_req_recv.initial_hdr.lct); +memset (&mgr->up_req_recv,0 ,sizeof (struct drm_dp_sideband_msg_rx )); +return 0 ; + } +drm_dp_update_port (mstb, &msg.u.conn_stat);DRM_DEBUG_KMS ("Got CSN: pn: %d ldps:%d ddps: %d mcs: %d ip: %d pdt: %d\n" , msg.u.conn_stat.port_number, msg.u.conn_stat.legacy_device_plug_status, msg.u.conn_stat.displayport_device_plug_status, msg.u.conn_stat.message_capability_status, msg.u.conn_stat.input_port, msg.u.conn_stat.peer_device_type); (*mgr->cbs->hotplug)(mgr); }else if (msg.req_type ==DP_RESOURCE_STATUS_NOTIFY ) { -drm_dp_send_up_ack_reply (mgr, mstb, msg.req_type, seqno, false); +drm_dp_send_up_ack_reply (mgr, mgr->mst_primary, msg.req_type, seqno, false); +if (!mstb) + mstb =drm_dp_get_mst_branch_device_by_guid (mgr, msg.u.resource_stat.guid); + +if (!mstb) { +DRM_DEBUG_KMS ("Got MST reply from unknown device %d\n" , mgr->up_req_recv.initial_hdr.lct); +memset (&mgr->up_req_recv,0 ,sizeof (struct drm_dp_sideband_msg_rx )); +return 0 ; + } +DRM_DEBUG_KMS ("Got RSN: pn: %d avail_pbn %d\n" , msg.u.resource_stat.port_number, msg.u.resource_stat.available_pbn); }
Patches currently in stable-queue which might be from [email protected] are
queue-4.4/drm-dp-mst-deallocate-payload-on-port-destruction.patch queue-4.4/drm-dp-mst-process-broadcast-messages-correctly.patch queue-4.4/drm-dp-mst-fix-in-rad-element-access.patch queue-4.4/drm-dp-mst-always-send-reply-for-up-request.patch queue-4.4/drm-dp-mst-fix-in-mstb-rad-initialization.patch