@@ -341,6 +341,7 @@ struct tcpm_port {
341
341
bool vbus_source ;
342
342
bool vbus_charge ;
343
343
344
+ /* Set to true when Discover_Identity Command is expected to be sent in Ready states. */
344
345
bool send_discover ;
345
346
bool op_vsafe5v ;
346
347
@@ -370,6 +371,7 @@ struct tcpm_port {
370
371
struct hrtimer send_discover_timer ;
371
372
struct kthread_work send_discover_work ;
372
373
bool state_machine_running ;
374
+ /* Set to true when VDM State Machine has following actions. */
373
375
bool vdm_sm_running ;
374
376
375
377
struct completion tx_complete ;
@@ -1431,6 +1433,7 @@ static void tcpm_queue_vdm(struct tcpm_port *port, const u32 header,
1431
1433
/* Set ready, vdm state machine will actually send */
1432
1434
port -> vdm_retries = 0 ;
1433
1435
port -> vdm_state = VDM_STATE_READY ;
1436
+ port -> vdm_sm_running = true;
1434
1437
1435
1438
mod_vdm_delayed_work (port , 0 );
1436
1439
}
@@ -1673,7 +1676,6 @@ static int tcpm_pd_svdm(struct tcpm_port *port, struct typec_altmode *adev,
1673
1676
rlen = 1 ;
1674
1677
} else {
1675
1678
tcpm_register_partner_altmodes (port );
1676
- port -> vdm_sm_running = false;
1677
1679
}
1678
1680
break ;
1679
1681
case CMD_ENTER_MODE :
@@ -1721,14 +1723,12 @@ static int tcpm_pd_svdm(struct tcpm_port *port, struct typec_altmode *adev,
1721
1723
(VDO_SVDM_VERS (svdm_version ));
1722
1724
break ;
1723
1725
}
1724
- port -> vdm_sm_running = false;
1725
1726
break ;
1726
1727
default :
1727
1728
response [0 ] = p [0 ] | VDO_CMDT (CMDT_RSP_NAK );
1728
1729
rlen = 1 ;
1729
1730
response [0 ] = (response [0 ] & ~VDO_SVDM_VERS_MASK ) |
1730
1731
(VDO_SVDM_VERS (svdm_version ));
1731
- port -> vdm_sm_running = false;
1732
1732
break ;
1733
1733
}
1734
1734
@@ -1769,6 +1769,20 @@ static void tcpm_handle_vdm_request(struct tcpm_port *port,
1769
1769
}
1770
1770
1771
1771
if (PD_VDO_SVDM (p [0 ]) && (adev || tcpm_vdm_ams (port ) || port -> nr_snk_vdo )) {
1772
+ /*
1773
+ * Here a SVDM is received (INIT or RSP or unknown). Set the vdm_sm_running in
1774
+ * advance because we are dropping the lock but may send VDMs soon.
1775
+ * For the cases of INIT received:
1776
+ * - If no response to send, it will be cleared later in this function.
1777
+ * - If there are responses to send, it will be cleared in the state machine.
1778
+ * For the cases of RSP received:
1779
+ * - If no further INIT to send, it will be cleared later in this function.
1780
+ * - Otherwise, it will be cleared in the state machine if timeout or it will go
1781
+ * back here until no further INIT to send.
1782
+ * For the cases of unknown type received:
1783
+ * - We will send NAK and the flag will be cleared in the state machine.
1784
+ */
1785
+ port -> vdm_sm_running = true;
1772
1786
rlen = tcpm_pd_svdm (port , adev , p , cnt , response , & adev_action );
1773
1787
} else {
1774
1788
if (port -> negotiated_rev >= PD_REV30 )
@@ -1837,6 +1851,8 @@ static void tcpm_handle_vdm_request(struct tcpm_port *port,
1837
1851
1838
1852
if (rlen > 0 )
1839
1853
tcpm_queue_vdm (port , response [0 ], & response [1 ], rlen - 1 );
1854
+ else
1855
+ port -> vdm_sm_running = false;
1840
1856
}
1841
1857
1842
1858
static void tcpm_send_vdm (struct tcpm_port * port , u32 vid , int cmd ,
@@ -1902,8 +1918,10 @@ static void vdm_run_state_machine(struct tcpm_port *port)
1902
1918
* if there's traffic or we're not in PDO ready state don't send
1903
1919
* a VDM.
1904
1920
*/
1905
- if (port -> state != SRC_READY && port -> state != SNK_READY )
1921
+ if (port -> state != SRC_READY && port -> state != SNK_READY ) {
1922
+ port -> vdm_sm_running = false;
1906
1923
break ;
1924
+ }
1907
1925
1908
1926
/* TODO: AMS operation for Unstructured VDM */
1909
1927
if (PD_VDO_SVDM (vdo_hdr ) && PD_VDO_CMDT (vdo_hdr ) == CMDT_INIT ) {
@@ -2556,10 +2574,6 @@ static void tcpm_pd_ctrl_request(struct tcpm_port *port,
2556
2574
TYPEC_PWR_MODE_PD ,
2557
2575
port -> pps_data .active ,
2558
2576
port -> supply_voltage );
2559
- /* Set VDM running flag ASAP */
2560
- if (port -> data_role == TYPEC_HOST &&
2561
- port -> send_discover )
2562
- port -> vdm_sm_running = true;
2563
2577
tcpm_set_state (port , SNK_READY , 0 );
2564
2578
} else {
2565
2579
/*
@@ -2597,14 +2611,10 @@ static void tcpm_pd_ctrl_request(struct tcpm_port *port,
2597
2611
switch (port -> state ) {
2598
2612
case SNK_NEGOTIATE_CAPABILITIES :
2599
2613
/* USB PD specification, Figure 8-43 */
2600
- if (port -> explicit_contract ) {
2614
+ if (port -> explicit_contract )
2601
2615
next_state = SNK_READY ;
2602
- if (port -> data_role == TYPEC_HOST &&
2603
- port -> send_discover )
2604
- port -> vdm_sm_running = true;
2605
- } else {
2616
+ else
2606
2617
next_state = SNK_WAIT_CAPABILITIES ;
2607
- }
2608
2618
2609
2619
/* Threshold was relaxed before sending Request. Restore it back. */
2610
2620
tcpm_set_auto_vbus_discharge_threshold (port , TYPEC_PWR_MODE_PD ,
@@ -2619,10 +2629,6 @@ static void tcpm_pd_ctrl_request(struct tcpm_port *port,
2619
2629
port -> pps_status = (type == PD_CTRL_WAIT ?
2620
2630
- EAGAIN : - EOPNOTSUPP );
2621
2631
2622
- if (port -> data_role == TYPEC_HOST &&
2623
- port -> send_discover )
2624
- port -> vdm_sm_running = true;
2625
-
2626
2632
/* Threshold was relaxed before sending Request. Restore it back. */
2627
2633
tcpm_set_auto_vbus_discharge_threshold (port , TYPEC_PWR_MODE_PD ,
2628
2634
port -> pps_data .active ,
@@ -2698,10 +2704,6 @@ static void tcpm_pd_ctrl_request(struct tcpm_port *port,
2698
2704
}
2699
2705
break ;
2700
2706
case DR_SWAP_SEND :
2701
- if (port -> data_role == TYPEC_DEVICE &&
2702
- port -> send_discover )
2703
- port -> vdm_sm_running = true;
2704
-
2705
2707
tcpm_set_state (port , DR_SWAP_CHANGE_DR , 0 );
2706
2708
break ;
2707
2709
case PR_SWAP_SEND :
@@ -2739,7 +2741,7 @@ static void tcpm_pd_ctrl_request(struct tcpm_port *port,
2739
2741
PD_MSG_CTRL_NOT_SUPP ,
2740
2742
NONE_AMS );
2741
2743
} else {
2742
- if (port -> vdm_sm_running ) {
2744
+ if (port -> send_discover ) {
2743
2745
tcpm_queue_message (port , PD_MSG_CTRL_WAIT );
2744
2746
break ;
2745
2747
}
@@ -2755,7 +2757,7 @@ static void tcpm_pd_ctrl_request(struct tcpm_port *port,
2755
2757
PD_MSG_CTRL_NOT_SUPP ,
2756
2758
NONE_AMS );
2757
2759
} else {
2758
- if (port -> vdm_sm_running ) {
2760
+ if (port -> send_discover ) {
2759
2761
tcpm_queue_message (port , PD_MSG_CTRL_WAIT );
2760
2762
break ;
2761
2763
}
@@ -2764,7 +2766,7 @@ static void tcpm_pd_ctrl_request(struct tcpm_port *port,
2764
2766
}
2765
2767
break ;
2766
2768
case PD_CTRL_VCONN_SWAP :
2767
- if (port -> vdm_sm_running ) {
2769
+ if (port -> send_discover ) {
2768
2770
tcpm_queue_message (port , PD_MSG_CTRL_WAIT );
2769
2771
break ;
2770
2772
}
@@ -4480,18 +4482,20 @@ static void run_state_machine(struct tcpm_port *port)
4480
4482
/* DR_Swap states */
4481
4483
case DR_SWAP_SEND :
4482
4484
tcpm_pd_send_control (port , PD_CTRL_DR_SWAP );
4485
+ if (port -> data_role == TYPEC_DEVICE || port -> negotiated_rev > PD_REV20 )
4486
+ port -> send_discover = true;
4483
4487
tcpm_set_state_cond (port , DR_SWAP_SEND_TIMEOUT ,
4484
4488
PD_T_SENDER_RESPONSE );
4485
4489
break ;
4486
4490
case DR_SWAP_ACCEPT :
4487
4491
tcpm_pd_send_control (port , PD_CTRL_ACCEPT );
4488
- /* Set VDM state machine running flag ASAP */
4489
- if (port -> data_role == TYPEC_DEVICE && port -> send_discover )
4490
- port -> vdm_sm_running = true;
4492
+ if (port -> data_role == TYPEC_DEVICE || port -> negotiated_rev > PD_REV20 )
4493
+ port -> send_discover = true;
4491
4494
tcpm_set_state_cond (port , DR_SWAP_CHANGE_DR , 0 );
4492
4495
break ;
4493
4496
case DR_SWAP_SEND_TIMEOUT :
4494
4497
tcpm_swap_complete (port , - ETIMEDOUT );
4498
+ port -> send_discover = false;
4495
4499
tcpm_ams_finish (port );
4496
4500
tcpm_set_state (port , ready_state (port ), 0 );
4497
4501
break ;
@@ -4503,7 +4507,6 @@ static void run_state_machine(struct tcpm_port *port)
4503
4507
} else {
4504
4508
tcpm_set_roles (port , true, port -> pwr_role ,
4505
4509
TYPEC_HOST );
4506
- port -> send_discover = true;
4507
4510
}
4508
4511
tcpm_ams_finish (port );
4509
4512
tcpm_set_state (port , ready_state (port ), 0 );
@@ -4646,8 +4649,6 @@ static void run_state_machine(struct tcpm_port *port)
4646
4649
break ;
4647
4650
case VCONN_SWAP_SEND_TIMEOUT :
4648
4651
tcpm_swap_complete (port , - ETIMEDOUT );
4649
- if (port -> data_role == TYPEC_HOST && port -> send_discover )
4650
- port -> vdm_sm_running = true;
4651
4652
tcpm_set_state (port , ready_state (port ), 0 );
4652
4653
break ;
4653
4654
case VCONN_SWAP_START :
@@ -4663,23 +4664,17 @@ static void run_state_machine(struct tcpm_port *port)
4663
4664
case VCONN_SWAP_TURN_ON_VCONN :
4664
4665
tcpm_set_vconn (port , true);
4665
4666
tcpm_pd_send_control (port , PD_CTRL_PS_RDY );
4666
- if (port -> data_role == TYPEC_HOST && port -> send_discover )
4667
- port -> vdm_sm_running = true;
4668
4667
tcpm_set_state (port , ready_state (port ), 0 );
4669
4668
break ;
4670
4669
case VCONN_SWAP_TURN_OFF_VCONN :
4671
4670
tcpm_set_vconn (port , false);
4672
- if (port -> data_role == TYPEC_HOST && port -> send_discover )
4673
- port -> vdm_sm_running = true;
4674
4671
tcpm_set_state (port , ready_state (port ), 0 );
4675
4672
break ;
4676
4673
4677
4674
case DR_SWAP_CANCEL :
4678
4675
case PR_SWAP_CANCEL :
4679
4676
case VCONN_SWAP_CANCEL :
4680
4677
tcpm_swap_complete (port , port -> swap_status );
4681
- if (port -> data_role == TYPEC_HOST && port -> send_discover )
4682
- port -> vdm_sm_running = true;
4683
4678
if (port -> pwr_role == TYPEC_SOURCE )
4684
4679
tcpm_set_state (port , SRC_READY , 0 );
4685
4680
else
@@ -5029,9 +5024,6 @@ static void _tcpm_pd_vbus_on(struct tcpm_port *port)
5029
5024
switch (port -> state ) {
5030
5025
case SNK_TRANSITION_SINK_VBUS :
5031
5026
port -> explicit_contract = true;
5032
- /* Set the VDM flag ASAP */
5033
- if (port -> data_role == TYPEC_HOST && port -> send_discover )
5034
- port -> vdm_sm_running = true;
5035
5027
tcpm_set_state (port , SNK_READY , 0 );
5036
5028
break ;
5037
5029
case SNK_DISCOVERY :
@@ -5426,15 +5418,18 @@ static void tcpm_send_discover_work(struct kthread_work *work)
5426
5418
if (!port -> send_discover )
5427
5419
goto unlock ;
5428
5420
5421
+ if (port -> data_role == TYPEC_DEVICE && port -> negotiated_rev < PD_REV30 ) {
5422
+ port -> send_discover = false;
5423
+ goto unlock ;
5424
+ }
5425
+
5429
5426
/* Retry if the port is not idle */
5430
5427
if ((port -> state != SRC_READY && port -> state != SNK_READY ) || port -> vdm_sm_running ) {
5431
5428
mod_send_discover_delayed_work (port , SEND_DISCOVER_RETRY_MS );
5432
5429
goto unlock ;
5433
5430
}
5434
5431
5435
- /* Only send the Message if the port is host for PD rev2.0 */
5436
- if (port -> data_role == TYPEC_HOST || port -> negotiated_rev > PD_REV20 )
5437
- tcpm_send_vdm (port , USB_SID_PD , CMD_DISCOVER_IDENT , NULL , 0 );
5432
+ tcpm_send_vdm (port , USB_SID_PD , CMD_DISCOVER_IDENT , NULL , 0 );
5438
5433
5439
5434
unlock :
5440
5435
mutex_unlock (& port -> lock );
0 commit comments