Loading drivers/usb/pd/policy_engine.c +130 −126 Original line number Diff line number Diff line Loading @@ -51,7 +51,6 @@ enum usbpd_state { PE_SRC_READY, PE_SRC_HARD_RESET, PE_SRC_SOFT_RESET, PE_SRC_SEND_SOFT_RESET, PE_SRC_DISCOVERY, PE_SRC_TRANSITION_TO_DEFAULT, PE_SNK_STARTUP, Loading @@ -63,7 +62,6 @@ enum usbpd_state { PE_SNK_READY, PE_SNK_HARD_RESET, PE_SNK_SOFT_RESET, PE_SNK_SEND_SOFT_RESET, PE_SNK_TRANSITION_TO_DEFAULT, PE_DRS_SEND_DR_SWAP, PE_PRS_SNK_SRC_SEND_SWAP, Loading @@ -72,6 +70,7 @@ enum usbpd_state { PE_PRS_SRC_SNK_SEND_SWAP, PE_PRS_SRC_SNK_TRANSITION_TO_OFF, PE_PRS_SRC_SNK_WAIT_SOURCE_ON, PE_SEND_SOFT_RESET, PE_VCS_WAIT_FOR_VCONN, }; Loading @@ -88,7 +87,6 @@ static const char * const usbpd_state_strings[] = { "SRC_Ready", "SRC_Hard_Reset", "SRC_Soft_Reset", "SRC_Send_Soft_Reset", "SRC_Discovery", "SRC_Transition_to_default", "SNK_Startup", Loading @@ -100,7 +98,6 @@ static const char * const usbpd_state_strings[] = { "SNK_Ready", "SNK_Hard_Reset", "SNK_Soft_Reset", "SNK_Send_Soft_Reset", "SNK_Transition_to_default", "DRS_Send_DR_Swap", "PRS_SNK_SRC_Send_Swap", Loading @@ -109,6 +106,7 @@ static const char * const usbpd_state_strings[] = { "PRS_SRC_SNK_Send_Swap", "PRS_SRC_SNK_Transition_to_off", "PRS_SRC_SNK_Wait_Source_on", "Send_Soft_Reset", "VCS_Wait_for_VCONN", }; Loading Loading @@ -1337,7 +1335,7 @@ static void usbpd_set_state(struct usbpd *pd, enum usbpd_state next_state) /* send Reject */ ret = pd_send_msg(pd, MSG_REJECT, NULL, 0, SOP_MSG); if (ret) { usbpd_set_state(pd, PE_SRC_SEND_SOFT_RESET); usbpd_set_state(pd, PE_SEND_SOFT_RESET); break; } Loading @@ -1358,7 +1356,7 @@ static void usbpd_set_state(struct usbpd *pd, enum usbpd_state next_state) /* PE_SRC_TRANSITION_SUPPLY pseudo-state */ ret = pd_send_msg(pd, MSG_ACCEPT, NULL, 0, SOP_MSG); if (ret) { usbpd_set_state(pd, PE_SRC_SEND_SOFT_RESET); usbpd_set_state(pd, PE_SEND_SOFT_RESET); break; } Loading @@ -1373,7 +1371,7 @@ static void usbpd_set_state(struct usbpd *pd, enum usbpd_state next_state) */ ret = pd_send_msg(pd, MSG_PS_RDY, NULL, 0, SOP_MSG); if (ret) { usbpd_set_state(pd, PE_SRC_SEND_SOFT_RESET); usbpd_set_state(pd, PE_SEND_SOFT_RESET); break; } Loading Loading @@ -1425,8 +1423,7 @@ static void usbpd_set_state(struct usbpd *pd, enum usbpd_state next_state) kick_sm(pd, 0); break; case PE_SRC_SEND_SOFT_RESET: case PE_SNK_SEND_SOFT_RESET: case PE_SEND_SOFT_RESET: pd_reset_protocol(pd); ret = pd_send_msg(pd, MSG_SOFT_RESET, NULL, 0, SOP_MSG); Loading Loading @@ -1516,7 +1513,7 @@ static void usbpd_set_state(struct usbpd *pd, enum usbpd_state next_state) ret = pd_send_msg(pd, MSG_REQUEST, &pd->rdo, 1, SOP_MSG); if (ret) { usbpd_set_state(pd, PE_SNK_SEND_SOFT_RESET); usbpd_set_state(pd, PE_SEND_SOFT_RESET); break; } Loading Loading @@ -1940,9 +1937,7 @@ static void handle_vdm_tx(struct usbpd *pd, enum pd_sop_type sop_type) /* retry when hitting PE_SRC/SNK_Ready again */ if (ret != -EBUSY && sop_type == SOP_MSG) usbpd_set_state(pd, pd->current_pr == PR_SRC ? PE_SRC_SEND_SOFT_RESET : PE_SNK_SEND_SOFT_RESET); usbpd_set_state(pd, PE_SEND_SOFT_RESET); return; } Loading Loading @@ -2043,9 +2038,7 @@ static void vconn_swap(struct usbpd *pd) ret = pd_send_msg(pd, MSG_PS_RDY, NULL, 0, SOP_MSG); if (ret) { usbpd_set_state(pd, pd->current_pr == PR_SRC ? PE_SRC_SEND_SOFT_RESET : PE_SNK_SEND_SOFT_RESET); usbpd_set_state(pd, PE_SEND_SOFT_RESET); return; } } Loading Loading @@ -2371,7 +2364,7 @@ static void usbpd_sm(struct work_struct *w) usbpd_set_state(pd, PE_SRC_NEGOTIATE_CAPABILITY); } else if (rx_msg) { usbpd_err(&pd->dev, "Unexpected message received\n"); usbpd_set_state(pd, PE_SRC_SEND_SOFT_RESET); usbpd_set_state(pd, PE_SEND_SOFT_RESET); } else { usbpd_set_state(pd, PE_SRC_HARD_RESET); } Loading @@ -2386,7 +2379,7 @@ static void usbpd_sm(struct work_struct *w) pd->sink_caps, pd->num_sink_caps, SOP_MSG); if (ret) usbpd_set_state(pd, PE_SRC_SEND_SOFT_RESET); usbpd_set_state(pd, PE_SEND_SOFT_RESET); } else if (IS_DATA(rx_msg, MSG_REQUEST)) { pd->rdo = *(u32 *)rx_msg->payload; usbpd_set_state(pd, PE_SRC_NEGOTIATE_CAPABILITY); Loading @@ -2398,7 +2391,7 @@ static void usbpd_sm(struct work_struct *w) ret = pd_send_msg(pd, MSG_ACCEPT, NULL, 0, SOP_MSG); if (ret) { usbpd_set_state(pd, PE_SRC_SEND_SOFT_RESET); usbpd_set_state(pd, PE_SEND_SOFT_RESET); break; } Loading @@ -2407,7 +2400,7 @@ static void usbpd_sm(struct work_struct *w) /* we'll happily accept Src->Sink requests anytime */ ret = pd_send_msg(pd, MSG_ACCEPT, NULL, 0, SOP_MSG); if (ret) { usbpd_set_state(pd, PE_SRC_SEND_SOFT_RESET); usbpd_set_state(pd, PE_SEND_SOFT_RESET); break; } Loading @@ -2416,7 +2409,7 @@ static void usbpd_sm(struct work_struct *w) } else if (IS_CTRL(rx_msg, MSG_VCONN_SWAP)) { ret = pd_send_msg(pd, MSG_ACCEPT, NULL, 0, SOP_MSG); if (ret) { usbpd_set_state(pd, PE_SRC_SEND_SOFT_RESET); usbpd_set_state(pd, PE_SEND_SOFT_RESET); break; } Loading @@ -2428,13 +2421,13 @@ static void usbpd_sm(struct work_struct *w) ret = pd_send_msg(pd, MSG_NOT_SUPPORTED, NULL, 0, SOP_MSG); if (ret) usbpd_set_state(pd, PE_SRC_SEND_SOFT_RESET); usbpd_set_state(pd, PE_SEND_SOFT_RESET); break; } else if (pd->send_pr_swap) { pd->send_pr_swap = false; ret = pd_send_msg(pd, MSG_PR_SWAP, NULL, 0, SOP_MSG); if (ret) { usbpd_set_state(pd, PE_SRC_SEND_SOFT_RESET); usbpd_set_state(pd, PE_SEND_SOFT_RESET); break; } Loading @@ -2444,7 +2437,7 @@ static void usbpd_sm(struct work_struct *w) pd->send_dr_swap = false; ret = pd_send_msg(pd, MSG_DR_SWAP, NULL, 0, SOP_MSG); if (ret) { usbpd_set_state(pd, PE_SRC_SEND_SOFT_RESET); usbpd_set_state(pd, PE_SEND_SOFT_RESET); break; } Loading Loading @@ -2608,7 +2601,7 @@ static void usbpd_sm(struct work_struct *w) PE_SNK_WAIT_FOR_CAPABILITIES); } else if (rx_msg) { usbpd_err(&pd->dev, "Invalid response to sink request\n"); usbpd_set_state(pd, PE_SNK_SEND_SOFT_RESET); usbpd_set_state(pd, PE_SEND_SOFT_RESET); } else { /* timed out; go to hard reset */ usbpd_set_state(pd, PE_SNK_HARD_RESET); Loading Loading @@ -2647,21 +2640,22 @@ static void usbpd_sm(struct work_struct *w) pd->src_cap_id++; usbpd_set_state(pd, PE_SNK_EVALUATE_CAPABILITY); break; } else if (IS_CTRL(rx_msg, MSG_GET_SINK_CAP)) { ret = pd_send_msg(pd, MSG_SINK_CAPABILITIES, pd->sink_caps, pd->num_sink_caps, SOP_MSG); if (ret) usbpd_set_state(pd, PE_SNK_SEND_SOFT_RESET); usbpd_set_state(pd, PE_SEND_SOFT_RESET); break; } else if (IS_CTRL(rx_msg, MSG_GET_SOURCE_CAP) && pd->spec_rev == USBPD_REV_20) { ret = pd_send_msg(pd, MSG_SOURCE_CAPABILITIES, default_src_caps, ARRAY_SIZE(default_src_caps), SOP_MSG); if (ret) { usbpd_set_state(pd, PE_SNK_SEND_SOFT_RESET); if (ret) usbpd_set_state(pd, PE_SEND_SOFT_RESET); break; } } else if (IS_CTRL(rx_msg, MSG_DR_SWAP)) { if (pd->vdm_state == MODE_ENTERED) { usbpd_set_state(pd, PE_SNK_HARD_RESET); Loading @@ -2670,17 +2664,18 @@ static void usbpd_sm(struct work_struct *w) ret = pd_send_msg(pd, MSG_ACCEPT, NULL, 0, SOP_MSG); if (ret) { usbpd_set_state(pd, PE_SRC_SEND_SOFT_RESET); usbpd_set_state(pd, PE_SEND_SOFT_RESET); break; } dr_swap(pd); break; } else if (IS_CTRL(rx_msg, MSG_PR_SWAP) && pd->spec_rev == USBPD_REV_20) { /* TODO: should we Reject in certain circumstances? */ ret = pd_send_msg(pd, MSG_ACCEPT, NULL, 0, SOP_MSG); if (ret) { usbpd_set_state(pd, PE_SNK_SEND_SOFT_RESET); usbpd_set_state(pd, PE_SEND_SOFT_RESET); break; } Loading @@ -2697,57 +2692,22 @@ static void usbpd_sm(struct work_struct *w) ret = pd_send_msg(pd, MSG_REJECT, NULL, 0, SOP_MSG); if (ret) usbpd_set_state(pd, PE_SNK_SEND_SOFT_RESET); usbpd_set_state(pd, PE_SEND_SOFT_RESET); break; } ret = pd_send_msg(pd, MSG_ACCEPT, NULL, 0, SOP_MSG); if (ret) { usbpd_set_state(pd, PE_SNK_SEND_SOFT_RESET); usbpd_set_state(pd, PE_SEND_SOFT_RESET); break; } vconn_swap(pd); break; } else if (IS_DATA(rx_msg, MSG_VDM)) { handle_vdm_rx(pd, rx_msg); } else if (pd->send_get_src_cap_ext && is_sink_tx_ok(pd)) { pd->send_get_src_cap_ext = false; ret = pd_send_msg(pd, MSG_GET_SOURCE_CAP_EXTENDED, NULL, 0, SOP_MSG); if (ret) { usbpd_set_state(pd, PE_SNK_SEND_SOFT_RESET); break; } kick_sm(pd, SENDER_RESPONSE_TIME); } else if (rx_msg && IS_EXT(rx_msg, MSG_SOURCE_CAPABILITIES_EXTENDED)) { if (rx_msg->data_len != PD_SRC_CAP_EXT_DB_LEN) { usbpd_err(&pd->dev, "Invalid src cap ext db\n"); break; } memcpy(&pd->src_cap_ext_db, rx_msg->payload, sizeof(pd->src_cap_ext_db)); complete(&pd->is_ready); } else if (pd->send_get_pps_status && is_sink_tx_ok(pd)) { pd->send_get_pps_status = false; ret = pd_send_msg(pd, MSG_GET_PPS_STATUS, NULL, 0, SOP_MSG); if (ret) { usbpd_set_state(pd, PE_SNK_SEND_SOFT_RESET); break; } kick_sm(pd, SENDER_RESPONSE_TIME); } else if (rx_msg && IS_EXT(rx_msg, MSG_PPS_STATUS)) { if (rx_msg->data_len != sizeof(pd->pps_status_db)) { usbpd_err(&pd->dev, "Invalid pps status db\n"); break; } memcpy(&pd->pps_status_db, rx_msg->payload, sizeof(pd->pps_status_db)); complete(&pd->is_ready); } else if (IS_DATA(rx_msg, MSG_ALERT)) { u32 ado; Loading @@ -2765,15 +2725,24 @@ static void usbpd_sm(struct work_struct *w) */ pd->send_get_status = true; kick_sm(pd, 150); } else if (pd->send_get_status && is_sink_tx_ok(pd)) { pd->send_get_status = false; ret = pd_send_msg(pd, MSG_GET_STATUS, NULL, 0, SOP_MSG); if (ret) { usbpd_set_state(pd, PE_SNK_SEND_SOFT_RESET); break; } else if (IS_EXT(rx_msg, MSG_SOURCE_CAPABILITIES_EXTENDED)) { if (rx_msg->data_len != PD_SRC_CAP_EXT_DB_LEN) { usbpd_err(&pd->dev, "Invalid src cap ext db\n"); break; } kick_sm(pd, SENDER_RESPONSE_TIME); } else if (rx_msg && IS_EXT(rx_msg, MSG_STATUS)) { memcpy(&pd->src_cap_ext_db, rx_msg->payload, sizeof(pd->src_cap_ext_db)); complete(&pd->is_ready); } else if (IS_EXT(rx_msg, MSG_PPS_STATUS)) { if (rx_msg->data_len != sizeof(pd->pps_status_db)) { usbpd_err(&pd->dev, "Invalid pps status db\n"); break; } memcpy(&pd->pps_status_db, rx_msg->payload, sizeof(pd->pps_status_db)); complete(&pd->is_ready); } else if (IS_EXT(rx_msg, MSG_STATUS)) { if (rx_msg->data_len != PD_STATUS_DB_LEN) { usbpd_err(&pd->dev, "Invalid status db\n"); break; Loading @@ -2781,17 +2750,8 @@ static void usbpd_sm(struct work_struct *w) memcpy(&pd->status_db, rx_msg->payload, sizeof(pd->status_db)); kobject_uevent(&pd->dev.kobj, KOBJ_CHANGE); } else if (pd->send_get_battery_cap && is_sink_tx_ok(pd)) { pd->send_get_battery_cap = false; ret = pd_send_ext_msg(pd, MSG_GET_BATTERY_CAP, &pd->get_battery_cap_db, 1, SOP_MSG); if (ret) { usbpd_set_state(pd, PE_SNK_SEND_SOFT_RESET); break; } kick_sm(pd, SENDER_RESPONSE_TIME); } else if (rx_msg && IS_EXT(rx_msg, MSG_BATTERY_CAPABILITIES)) { complete(&pd->is_ready); } else if (IS_EXT(rx_msg, MSG_BATTERY_CAPABILITIES)) { if (rx_msg->data_len != PD_BATTERY_CAP_DB_LEN) { usbpd_err(&pd->dev, "Invalid battery cap db\n"); break; Loading @@ -2799,17 +2759,7 @@ static void usbpd_sm(struct work_struct *w) memcpy(&pd->battery_cap_db, rx_msg->payload, sizeof(pd->battery_cap_db)); complete(&pd->is_ready); } else if (pd->send_get_battery_status && is_sink_tx_ok(pd)) { pd->send_get_battery_status = false; ret = pd_send_ext_msg(pd, MSG_GET_BATTERY_STATUS, &pd->get_battery_status_db, 1, SOP_MSG); if (ret) { usbpd_set_state(pd, PE_SNK_SEND_SOFT_RESET); break; } kick_sm(pd, SENDER_RESPONSE_TIME); } else if (rx_msg && IS_EXT(rx_msg, MSG_BATTERY_STATUS)) { } else if (IS_EXT(rx_msg, MSG_BATTERY_STATUS)) { if (rx_msg->data_len != sizeof(pd->battery_sts_dobj)) { usbpd_err(&pd->dev, "Invalid bat sts dobj\n"); break; Loading @@ -2822,34 +2772,89 @@ static void usbpd_sm(struct work_struct *w) ret = pd_send_msg(pd, MSG_NOT_SUPPORTED, NULL, 0, SOP_MSG); if (ret) usbpd_set_state(pd, PE_SNK_SEND_SOFT_RESET); usbpd_set_state(pd, PE_SEND_SOFT_RESET); break; } /* handle outgoing requests */ if (is_sink_tx_ok(pd)) { if (pd->send_get_src_cap_ext) { pd->send_get_src_cap_ext = false; ret = pd_send_msg(pd, MSG_GET_SOURCE_CAP_EXTENDED, NULL, 0, SOP_MSG); if (ret) { usbpd_set_state(pd, PE_SEND_SOFT_RESET); break; } kick_sm(pd, SENDER_RESPONSE_TIME); } else if (pd->send_get_pps_status) { pd->send_get_pps_status = false; ret = pd_send_msg(pd, MSG_GET_PPS_STATUS, NULL, 0, SOP_MSG); if (ret) { usbpd_set_state(pd, PE_SEND_SOFT_RESET); break; } kick_sm(pd, SENDER_RESPONSE_TIME); } else if (pd->send_get_status) { pd->send_get_status = false; ret = pd_send_msg(pd, MSG_GET_STATUS, NULL, 0, SOP_MSG); if (ret) { usbpd_set_state(pd, PE_SEND_SOFT_RESET); break; } kick_sm(pd, SENDER_RESPONSE_TIME); } else if (pd->send_get_battery_cap) { pd->send_get_battery_cap = false; ret = pd_send_ext_msg(pd, MSG_GET_BATTERY_CAP, &pd->get_battery_cap_db, 1, SOP_MSG); if (ret) { usbpd_set_state(pd, PE_SEND_SOFT_RESET); break; } kick_sm(pd, SENDER_RESPONSE_TIME); } else if (pd->send_get_battery_status) { pd->send_get_battery_status = false; ret = pd_send_ext_msg(pd, MSG_GET_BATTERY_STATUS, &pd->get_battery_status_db, 1, SOP_MSG); if (ret) { usbpd_set_state(pd, PE_SEND_SOFT_RESET); break; } kick_sm(pd, SENDER_RESPONSE_TIME); } else if (pd->send_request) { pd->send_request = false; usbpd_set_state(pd, PE_SNK_SELECT_CAPABILITY); } else if (pd->send_pr_swap && is_sink_tx_ok(pd)) { } else if (pd->send_pr_swap) { pd->send_pr_swap = false; ret = pd_send_msg(pd, MSG_PR_SWAP, NULL, 0, SOP_MSG); ret = pd_send_msg(pd, MSG_PR_SWAP, NULL, 0, SOP_MSG); if (ret) { usbpd_set_state(pd, PE_SNK_SEND_SOFT_RESET); usbpd_set_state(pd, PE_SEND_SOFT_RESET); break; } pd->current_state = PE_PRS_SNK_SRC_SEND_SWAP; kick_sm(pd, SENDER_RESPONSE_TIME); } else if (pd->send_dr_swap && is_sink_tx_ok(pd)) { } else if (pd->send_dr_swap) { pd->send_dr_swap = false; ret = pd_send_msg(pd, MSG_DR_SWAP, NULL, 0, SOP_MSG); ret = pd_send_msg(pd, MSG_DR_SWAP, NULL, 0, SOP_MSG); if (ret) { usbpd_set_state(pd, PE_SNK_SEND_SOFT_RESET); usbpd_set_state(pd, PE_SEND_SOFT_RESET); break; } pd->current_state = PE_DRS_SEND_DR_SWAP; kick_sm(pd, SENDER_RESPONSE_TIME); } else if (is_sink_tx_ok(pd)) { } else { handle_vdm_tx(pd, SOP_MSG); } } break; case PE_SNK_TRANSITION_TO_DEFAULT: Loading @@ -2872,8 +2877,7 @@ static void usbpd_sm(struct work_struct *w) PE_SNK_WAIT_FOR_CAPABILITIES); break; case PE_SRC_SEND_SOFT_RESET: case PE_SNK_SEND_SOFT_RESET: case PE_SEND_SOFT_RESET: if (IS_CTRL(rx_msg, MSG_ACCEPT)) { usbpd_set_state(pd, pd->current_pr == PR_SRC ? PE_SRC_SEND_CAPABILITIES : Loading Loading
drivers/usb/pd/policy_engine.c +130 −126 Original line number Diff line number Diff line Loading @@ -51,7 +51,6 @@ enum usbpd_state { PE_SRC_READY, PE_SRC_HARD_RESET, PE_SRC_SOFT_RESET, PE_SRC_SEND_SOFT_RESET, PE_SRC_DISCOVERY, PE_SRC_TRANSITION_TO_DEFAULT, PE_SNK_STARTUP, Loading @@ -63,7 +62,6 @@ enum usbpd_state { PE_SNK_READY, PE_SNK_HARD_RESET, PE_SNK_SOFT_RESET, PE_SNK_SEND_SOFT_RESET, PE_SNK_TRANSITION_TO_DEFAULT, PE_DRS_SEND_DR_SWAP, PE_PRS_SNK_SRC_SEND_SWAP, Loading @@ -72,6 +70,7 @@ enum usbpd_state { PE_PRS_SRC_SNK_SEND_SWAP, PE_PRS_SRC_SNK_TRANSITION_TO_OFF, PE_PRS_SRC_SNK_WAIT_SOURCE_ON, PE_SEND_SOFT_RESET, PE_VCS_WAIT_FOR_VCONN, }; Loading @@ -88,7 +87,6 @@ static const char * const usbpd_state_strings[] = { "SRC_Ready", "SRC_Hard_Reset", "SRC_Soft_Reset", "SRC_Send_Soft_Reset", "SRC_Discovery", "SRC_Transition_to_default", "SNK_Startup", Loading @@ -100,7 +98,6 @@ static const char * const usbpd_state_strings[] = { "SNK_Ready", "SNK_Hard_Reset", "SNK_Soft_Reset", "SNK_Send_Soft_Reset", "SNK_Transition_to_default", "DRS_Send_DR_Swap", "PRS_SNK_SRC_Send_Swap", Loading @@ -109,6 +106,7 @@ static const char * const usbpd_state_strings[] = { "PRS_SRC_SNK_Send_Swap", "PRS_SRC_SNK_Transition_to_off", "PRS_SRC_SNK_Wait_Source_on", "Send_Soft_Reset", "VCS_Wait_for_VCONN", }; Loading Loading @@ -1337,7 +1335,7 @@ static void usbpd_set_state(struct usbpd *pd, enum usbpd_state next_state) /* send Reject */ ret = pd_send_msg(pd, MSG_REJECT, NULL, 0, SOP_MSG); if (ret) { usbpd_set_state(pd, PE_SRC_SEND_SOFT_RESET); usbpd_set_state(pd, PE_SEND_SOFT_RESET); break; } Loading @@ -1358,7 +1356,7 @@ static void usbpd_set_state(struct usbpd *pd, enum usbpd_state next_state) /* PE_SRC_TRANSITION_SUPPLY pseudo-state */ ret = pd_send_msg(pd, MSG_ACCEPT, NULL, 0, SOP_MSG); if (ret) { usbpd_set_state(pd, PE_SRC_SEND_SOFT_RESET); usbpd_set_state(pd, PE_SEND_SOFT_RESET); break; } Loading @@ -1373,7 +1371,7 @@ static void usbpd_set_state(struct usbpd *pd, enum usbpd_state next_state) */ ret = pd_send_msg(pd, MSG_PS_RDY, NULL, 0, SOP_MSG); if (ret) { usbpd_set_state(pd, PE_SRC_SEND_SOFT_RESET); usbpd_set_state(pd, PE_SEND_SOFT_RESET); break; } Loading Loading @@ -1425,8 +1423,7 @@ static void usbpd_set_state(struct usbpd *pd, enum usbpd_state next_state) kick_sm(pd, 0); break; case PE_SRC_SEND_SOFT_RESET: case PE_SNK_SEND_SOFT_RESET: case PE_SEND_SOFT_RESET: pd_reset_protocol(pd); ret = pd_send_msg(pd, MSG_SOFT_RESET, NULL, 0, SOP_MSG); Loading Loading @@ -1516,7 +1513,7 @@ static void usbpd_set_state(struct usbpd *pd, enum usbpd_state next_state) ret = pd_send_msg(pd, MSG_REQUEST, &pd->rdo, 1, SOP_MSG); if (ret) { usbpd_set_state(pd, PE_SNK_SEND_SOFT_RESET); usbpd_set_state(pd, PE_SEND_SOFT_RESET); break; } Loading Loading @@ -1940,9 +1937,7 @@ static void handle_vdm_tx(struct usbpd *pd, enum pd_sop_type sop_type) /* retry when hitting PE_SRC/SNK_Ready again */ if (ret != -EBUSY && sop_type == SOP_MSG) usbpd_set_state(pd, pd->current_pr == PR_SRC ? PE_SRC_SEND_SOFT_RESET : PE_SNK_SEND_SOFT_RESET); usbpd_set_state(pd, PE_SEND_SOFT_RESET); return; } Loading Loading @@ -2043,9 +2038,7 @@ static void vconn_swap(struct usbpd *pd) ret = pd_send_msg(pd, MSG_PS_RDY, NULL, 0, SOP_MSG); if (ret) { usbpd_set_state(pd, pd->current_pr == PR_SRC ? PE_SRC_SEND_SOFT_RESET : PE_SNK_SEND_SOFT_RESET); usbpd_set_state(pd, PE_SEND_SOFT_RESET); return; } } Loading Loading @@ -2371,7 +2364,7 @@ static void usbpd_sm(struct work_struct *w) usbpd_set_state(pd, PE_SRC_NEGOTIATE_CAPABILITY); } else if (rx_msg) { usbpd_err(&pd->dev, "Unexpected message received\n"); usbpd_set_state(pd, PE_SRC_SEND_SOFT_RESET); usbpd_set_state(pd, PE_SEND_SOFT_RESET); } else { usbpd_set_state(pd, PE_SRC_HARD_RESET); } Loading @@ -2386,7 +2379,7 @@ static void usbpd_sm(struct work_struct *w) pd->sink_caps, pd->num_sink_caps, SOP_MSG); if (ret) usbpd_set_state(pd, PE_SRC_SEND_SOFT_RESET); usbpd_set_state(pd, PE_SEND_SOFT_RESET); } else if (IS_DATA(rx_msg, MSG_REQUEST)) { pd->rdo = *(u32 *)rx_msg->payload; usbpd_set_state(pd, PE_SRC_NEGOTIATE_CAPABILITY); Loading @@ -2398,7 +2391,7 @@ static void usbpd_sm(struct work_struct *w) ret = pd_send_msg(pd, MSG_ACCEPT, NULL, 0, SOP_MSG); if (ret) { usbpd_set_state(pd, PE_SRC_SEND_SOFT_RESET); usbpd_set_state(pd, PE_SEND_SOFT_RESET); break; } Loading @@ -2407,7 +2400,7 @@ static void usbpd_sm(struct work_struct *w) /* we'll happily accept Src->Sink requests anytime */ ret = pd_send_msg(pd, MSG_ACCEPT, NULL, 0, SOP_MSG); if (ret) { usbpd_set_state(pd, PE_SRC_SEND_SOFT_RESET); usbpd_set_state(pd, PE_SEND_SOFT_RESET); break; } Loading @@ -2416,7 +2409,7 @@ static void usbpd_sm(struct work_struct *w) } else if (IS_CTRL(rx_msg, MSG_VCONN_SWAP)) { ret = pd_send_msg(pd, MSG_ACCEPT, NULL, 0, SOP_MSG); if (ret) { usbpd_set_state(pd, PE_SRC_SEND_SOFT_RESET); usbpd_set_state(pd, PE_SEND_SOFT_RESET); break; } Loading @@ -2428,13 +2421,13 @@ static void usbpd_sm(struct work_struct *w) ret = pd_send_msg(pd, MSG_NOT_SUPPORTED, NULL, 0, SOP_MSG); if (ret) usbpd_set_state(pd, PE_SRC_SEND_SOFT_RESET); usbpd_set_state(pd, PE_SEND_SOFT_RESET); break; } else if (pd->send_pr_swap) { pd->send_pr_swap = false; ret = pd_send_msg(pd, MSG_PR_SWAP, NULL, 0, SOP_MSG); if (ret) { usbpd_set_state(pd, PE_SRC_SEND_SOFT_RESET); usbpd_set_state(pd, PE_SEND_SOFT_RESET); break; } Loading @@ -2444,7 +2437,7 @@ static void usbpd_sm(struct work_struct *w) pd->send_dr_swap = false; ret = pd_send_msg(pd, MSG_DR_SWAP, NULL, 0, SOP_MSG); if (ret) { usbpd_set_state(pd, PE_SRC_SEND_SOFT_RESET); usbpd_set_state(pd, PE_SEND_SOFT_RESET); break; } Loading Loading @@ -2608,7 +2601,7 @@ static void usbpd_sm(struct work_struct *w) PE_SNK_WAIT_FOR_CAPABILITIES); } else if (rx_msg) { usbpd_err(&pd->dev, "Invalid response to sink request\n"); usbpd_set_state(pd, PE_SNK_SEND_SOFT_RESET); usbpd_set_state(pd, PE_SEND_SOFT_RESET); } else { /* timed out; go to hard reset */ usbpd_set_state(pd, PE_SNK_HARD_RESET); Loading Loading @@ -2647,21 +2640,22 @@ static void usbpd_sm(struct work_struct *w) pd->src_cap_id++; usbpd_set_state(pd, PE_SNK_EVALUATE_CAPABILITY); break; } else if (IS_CTRL(rx_msg, MSG_GET_SINK_CAP)) { ret = pd_send_msg(pd, MSG_SINK_CAPABILITIES, pd->sink_caps, pd->num_sink_caps, SOP_MSG); if (ret) usbpd_set_state(pd, PE_SNK_SEND_SOFT_RESET); usbpd_set_state(pd, PE_SEND_SOFT_RESET); break; } else if (IS_CTRL(rx_msg, MSG_GET_SOURCE_CAP) && pd->spec_rev == USBPD_REV_20) { ret = pd_send_msg(pd, MSG_SOURCE_CAPABILITIES, default_src_caps, ARRAY_SIZE(default_src_caps), SOP_MSG); if (ret) { usbpd_set_state(pd, PE_SNK_SEND_SOFT_RESET); if (ret) usbpd_set_state(pd, PE_SEND_SOFT_RESET); break; } } else if (IS_CTRL(rx_msg, MSG_DR_SWAP)) { if (pd->vdm_state == MODE_ENTERED) { usbpd_set_state(pd, PE_SNK_HARD_RESET); Loading @@ -2670,17 +2664,18 @@ static void usbpd_sm(struct work_struct *w) ret = pd_send_msg(pd, MSG_ACCEPT, NULL, 0, SOP_MSG); if (ret) { usbpd_set_state(pd, PE_SRC_SEND_SOFT_RESET); usbpd_set_state(pd, PE_SEND_SOFT_RESET); break; } dr_swap(pd); break; } else if (IS_CTRL(rx_msg, MSG_PR_SWAP) && pd->spec_rev == USBPD_REV_20) { /* TODO: should we Reject in certain circumstances? */ ret = pd_send_msg(pd, MSG_ACCEPT, NULL, 0, SOP_MSG); if (ret) { usbpd_set_state(pd, PE_SNK_SEND_SOFT_RESET); usbpd_set_state(pd, PE_SEND_SOFT_RESET); break; } Loading @@ -2697,57 +2692,22 @@ static void usbpd_sm(struct work_struct *w) ret = pd_send_msg(pd, MSG_REJECT, NULL, 0, SOP_MSG); if (ret) usbpd_set_state(pd, PE_SNK_SEND_SOFT_RESET); usbpd_set_state(pd, PE_SEND_SOFT_RESET); break; } ret = pd_send_msg(pd, MSG_ACCEPT, NULL, 0, SOP_MSG); if (ret) { usbpd_set_state(pd, PE_SNK_SEND_SOFT_RESET); usbpd_set_state(pd, PE_SEND_SOFT_RESET); break; } vconn_swap(pd); break; } else if (IS_DATA(rx_msg, MSG_VDM)) { handle_vdm_rx(pd, rx_msg); } else if (pd->send_get_src_cap_ext && is_sink_tx_ok(pd)) { pd->send_get_src_cap_ext = false; ret = pd_send_msg(pd, MSG_GET_SOURCE_CAP_EXTENDED, NULL, 0, SOP_MSG); if (ret) { usbpd_set_state(pd, PE_SNK_SEND_SOFT_RESET); break; } kick_sm(pd, SENDER_RESPONSE_TIME); } else if (rx_msg && IS_EXT(rx_msg, MSG_SOURCE_CAPABILITIES_EXTENDED)) { if (rx_msg->data_len != PD_SRC_CAP_EXT_DB_LEN) { usbpd_err(&pd->dev, "Invalid src cap ext db\n"); break; } memcpy(&pd->src_cap_ext_db, rx_msg->payload, sizeof(pd->src_cap_ext_db)); complete(&pd->is_ready); } else if (pd->send_get_pps_status && is_sink_tx_ok(pd)) { pd->send_get_pps_status = false; ret = pd_send_msg(pd, MSG_GET_PPS_STATUS, NULL, 0, SOP_MSG); if (ret) { usbpd_set_state(pd, PE_SNK_SEND_SOFT_RESET); break; } kick_sm(pd, SENDER_RESPONSE_TIME); } else if (rx_msg && IS_EXT(rx_msg, MSG_PPS_STATUS)) { if (rx_msg->data_len != sizeof(pd->pps_status_db)) { usbpd_err(&pd->dev, "Invalid pps status db\n"); break; } memcpy(&pd->pps_status_db, rx_msg->payload, sizeof(pd->pps_status_db)); complete(&pd->is_ready); } else if (IS_DATA(rx_msg, MSG_ALERT)) { u32 ado; Loading @@ -2765,15 +2725,24 @@ static void usbpd_sm(struct work_struct *w) */ pd->send_get_status = true; kick_sm(pd, 150); } else if (pd->send_get_status && is_sink_tx_ok(pd)) { pd->send_get_status = false; ret = pd_send_msg(pd, MSG_GET_STATUS, NULL, 0, SOP_MSG); if (ret) { usbpd_set_state(pd, PE_SNK_SEND_SOFT_RESET); break; } else if (IS_EXT(rx_msg, MSG_SOURCE_CAPABILITIES_EXTENDED)) { if (rx_msg->data_len != PD_SRC_CAP_EXT_DB_LEN) { usbpd_err(&pd->dev, "Invalid src cap ext db\n"); break; } kick_sm(pd, SENDER_RESPONSE_TIME); } else if (rx_msg && IS_EXT(rx_msg, MSG_STATUS)) { memcpy(&pd->src_cap_ext_db, rx_msg->payload, sizeof(pd->src_cap_ext_db)); complete(&pd->is_ready); } else if (IS_EXT(rx_msg, MSG_PPS_STATUS)) { if (rx_msg->data_len != sizeof(pd->pps_status_db)) { usbpd_err(&pd->dev, "Invalid pps status db\n"); break; } memcpy(&pd->pps_status_db, rx_msg->payload, sizeof(pd->pps_status_db)); complete(&pd->is_ready); } else if (IS_EXT(rx_msg, MSG_STATUS)) { if (rx_msg->data_len != PD_STATUS_DB_LEN) { usbpd_err(&pd->dev, "Invalid status db\n"); break; Loading @@ -2781,17 +2750,8 @@ static void usbpd_sm(struct work_struct *w) memcpy(&pd->status_db, rx_msg->payload, sizeof(pd->status_db)); kobject_uevent(&pd->dev.kobj, KOBJ_CHANGE); } else if (pd->send_get_battery_cap && is_sink_tx_ok(pd)) { pd->send_get_battery_cap = false; ret = pd_send_ext_msg(pd, MSG_GET_BATTERY_CAP, &pd->get_battery_cap_db, 1, SOP_MSG); if (ret) { usbpd_set_state(pd, PE_SNK_SEND_SOFT_RESET); break; } kick_sm(pd, SENDER_RESPONSE_TIME); } else if (rx_msg && IS_EXT(rx_msg, MSG_BATTERY_CAPABILITIES)) { complete(&pd->is_ready); } else if (IS_EXT(rx_msg, MSG_BATTERY_CAPABILITIES)) { if (rx_msg->data_len != PD_BATTERY_CAP_DB_LEN) { usbpd_err(&pd->dev, "Invalid battery cap db\n"); break; Loading @@ -2799,17 +2759,7 @@ static void usbpd_sm(struct work_struct *w) memcpy(&pd->battery_cap_db, rx_msg->payload, sizeof(pd->battery_cap_db)); complete(&pd->is_ready); } else if (pd->send_get_battery_status && is_sink_tx_ok(pd)) { pd->send_get_battery_status = false; ret = pd_send_ext_msg(pd, MSG_GET_BATTERY_STATUS, &pd->get_battery_status_db, 1, SOP_MSG); if (ret) { usbpd_set_state(pd, PE_SNK_SEND_SOFT_RESET); break; } kick_sm(pd, SENDER_RESPONSE_TIME); } else if (rx_msg && IS_EXT(rx_msg, MSG_BATTERY_STATUS)) { } else if (IS_EXT(rx_msg, MSG_BATTERY_STATUS)) { if (rx_msg->data_len != sizeof(pd->battery_sts_dobj)) { usbpd_err(&pd->dev, "Invalid bat sts dobj\n"); break; Loading @@ -2822,34 +2772,89 @@ static void usbpd_sm(struct work_struct *w) ret = pd_send_msg(pd, MSG_NOT_SUPPORTED, NULL, 0, SOP_MSG); if (ret) usbpd_set_state(pd, PE_SNK_SEND_SOFT_RESET); usbpd_set_state(pd, PE_SEND_SOFT_RESET); break; } /* handle outgoing requests */ if (is_sink_tx_ok(pd)) { if (pd->send_get_src_cap_ext) { pd->send_get_src_cap_ext = false; ret = pd_send_msg(pd, MSG_GET_SOURCE_CAP_EXTENDED, NULL, 0, SOP_MSG); if (ret) { usbpd_set_state(pd, PE_SEND_SOFT_RESET); break; } kick_sm(pd, SENDER_RESPONSE_TIME); } else if (pd->send_get_pps_status) { pd->send_get_pps_status = false; ret = pd_send_msg(pd, MSG_GET_PPS_STATUS, NULL, 0, SOP_MSG); if (ret) { usbpd_set_state(pd, PE_SEND_SOFT_RESET); break; } kick_sm(pd, SENDER_RESPONSE_TIME); } else if (pd->send_get_status) { pd->send_get_status = false; ret = pd_send_msg(pd, MSG_GET_STATUS, NULL, 0, SOP_MSG); if (ret) { usbpd_set_state(pd, PE_SEND_SOFT_RESET); break; } kick_sm(pd, SENDER_RESPONSE_TIME); } else if (pd->send_get_battery_cap) { pd->send_get_battery_cap = false; ret = pd_send_ext_msg(pd, MSG_GET_BATTERY_CAP, &pd->get_battery_cap_db, 1, SOP_MSG); if (ret) { usbpd_set_state(pd, PE_SEND_SOFT_RESET); break; } kick_sm(pd, SENDER_RESPONSE_TIME); } else if (pd->send_get_battery_status) { pd->send_get_battery_status = false; ret = pd_send_ext_msg(pd, MSG_GET_BATTERY_STATUS, &pd->get_battery_status_db, 1, SOP_MSG); if (ret) { usbpd_set_state(pd, PE_SEND_SOFT_RESET); break; } kick_sm(pd, SENDER_RESPONSE_TIME); } else if (pd->send_request) { pd->send_request = false; usbpd_set_state(pd, PE_SNK_SELECT_CAPABILITY); } else if (pd->send_pr_swap && is_sink_tx_ok(pd)) { } else if (pd->send_pr_swap) { pd->send_pr_swap = false; ret = pd_send_msg(pd, MSG_PR_SWAP, NULL, 0, SOP_MSG); ret = pd_send_msg(pd, MSG_PR_SWAP, NULL, 0, SOP_MSG); if (ret) { usbpd_set_state(pd, PE_SNK_SEND_SOFT_RESET); usbpd_set_state(pd, PE_SEND_SOFT_RESET); break; } pd->current_state = PE_PRS_SNK_SRC_SEND_SWAP; kick_sm(pd, SENDER_RESPONSE_TIME); } else if (pd->send_dr_swap && is_sink_tx_ok(pd)) { } else if (pd->send_dr_swap) { pd->send_dr_swap = false; ret = pd_send_msg(pd, MSG_DR_SWAP, NULL, 0, SOP_MSG); ret = pd_send_msg(pd, MSG_DR_SWAP, NULL, 0, SOP_MSG); if (ret) { usbpd_set_state(pd, PE_SNK_SEND_SOFT_RESET); usbpd_set_state(pd, PE_SEND_SOFT_RESET); break; } pd->current_state = PE_DRS_SEND_DR_SWAP; kick_sm(pd, SENDER_RESPONSE_TIME); } else if (is_sink_tx_ok(pd)) { } else { handle_vdm_tx(pd, SOP_MSG); } } break; case PE_SNK_TRANSITION_TO_DEFAULT: Loading @@ -2872,8 +2877,7 @@ static void usbpd_sm(struct work_struct *w) PE_SNK_WAIT_FOR_CAPABILITIES); break; case PE_SRC_SEND_SOFT_RESET: case PE_SNK_SEND_SOFT_RESET: case PE_SEND_SOFT_RESET: if (IS_CTRL(rx_msg, MSG_ACCEPT)) { usbpd_set_state(pd, pd->current_pr == PR_SRC ? PE_SRC_SEND_CAPABILITIES : Loading