Skip to content

Commit 5e9c166

Browse files
lumaggregkh
authored andcommitted
usb: typec: ucsi: rework command execution functions
Rework command execution code to remove recursive calls of ucsi_exec_command. This also streamlines the sync_control / read(CCI) read (MESSAGE_IN) sequence, allowing further rework of the command code. Tested-by: Heikki Krogerus <[email protected]> Reviewed-by: Heikki Krogerus <[email protected]> Signed-off-by: Dmitry Baryshkov <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 467399d commit 5e9c166

File tree

1 file changed

+66
-72
lines changed

1 file changed

+66
-72
lines changed

drivers/usb/typec/ucsi/ucsi.c

Lines changed: 66 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -63,27 +63,76 @@ static int ucsi_acknowledge(struct ucsi *ucsi, bool conn_ack)
6363
return ucsi->ops->sync_control(ucsi, ctrl);
6464
}
6565

66-
static int ucsi_exec_command(struct ucsi *ucsi, u64 command);
66+
static int ucsi_run_command(struct ucsi *ucsi, u64 command, u32 *cci,
67+
void *data, size_t size, bool conn_ack)
68+
{
69+
int ret;
70+
71+
*cci = 0;
72+
73+
ret = ucsi->ops->sync_control(ucsi, command);
74+
if (ret)
75+
return ret;
76+
77+
ret = ucsi->ops->read_cci(ucsi, cci);
78+
if (ret)
79+
return ret;
80+
81+
if (*cci & UCSI_CCI_BUSY)
82+
return -EBUSY;
83+
84+
if (!(*cci & UCSI_CCI_COMMAND_COMPLETE))
85+
return -EIO;
86+
87+
if (*cci & UCSI_CCI_NOT_SUPPORTED) {
88+
if (ucsi_acknowledge(ucsi, false) < 0)
89+
dev_err(ucsi->dev,
90+
"ACK of unsupported command failed\n");
91+
return -EOPNOTSUPP;
92+
}
93+
94+
if (*cci & UCSI_CCI_ERROR) {
95+
/* Acknowledge the command that failed */
96+
ret = ucsi_acknowledge(ucsi, false);
97+
return ret ? ret : -EIO;
98+
}
99+
100+
if (data) {
101+
ret = ucsi_read_message_in(ucsi, data, size);
102+
if (ret)
103+
return ret;
104+
}
105+
106+
ret = ucsi_acknowledge(ucsi, conn_ack);
107+
if (ret)
108+
return ret;
109+
110+
return 0;
111+
}
67112

68113
static int ucsi_read_error(struct ucsi *ucsi, u8 connector_num)
69114
{
70115
u64 command;
71116
u16 error;
117+
u32 cci;
72118
int ret;
73119

74120
command = UCSI_GET_ERROR_STATUS | UCSI_CONNECTOR_NUMBER(connector_num);
75-
ret = ucsi_exec_command(ucsi, command);
76-
if (ret < 0)
77-
return ret;
121+
ret = ucsi_run_command(ucsi, command, &cci,
122+
&error, sizeof(error), false);
78123

79-
ret = ucsi_read_message_in(ucsi, &error, sizeof(error));
80-
if (ret)
81-
return ret;
124+
if (cci & UCSI_CCI_BUSY) {
125+
ret = ucsi_run_command(ucsi, UCSI_CANCEL, &cci, NULL, 0, false);
82126

83-
ret = ucsi_acknowledge(ucsi, false);
84-
if (ret)
127+
return ret ? ret : -EBUSY;
128+
}
129+
130+
if (ret < 0)
85131
return ret;
86132

133+
if (cci & UCSI_CCI_ERROR)
134+
return -EIO;
135+
87136
switch (error) {
88137
case UCSI_ERROR_INCOMPATIBLE_PARTNER:
89138
return -EOPNOTSUPP;
@@ -129,7 +178,8 @@ static int ucsi_read_error(struct ucsi *ucsi, u8 connector_num)
129178
return -EIO;
130179
}
131180

132-
static int ucsi_exec_command(struct ucsi *ucsi, u64 cmd)
181+
static int ucsi_send_command_common(struct ucsi *ucsi, u64 cmd,
182+
void *data, size_t size, bool conn_ack)
133183
{
134184
u8 connector_num;
135185
u32 cci;
@@ -155,73 +205,17 @@ static int ucsi_exec_command(struct ucsi *ucsi, u64 cmd)
155205
connector_num = 0;
156206
}
157207

158-
ret = ucsi->ops->sync_control(ucsi, cmd);
159-
if (ret)
160-
return ret;
161-
162-
ret = ucsi->ops->read_cci(ucsi, &cci);
163-
if (ret)
164-
return ret;
165-
166-
if (cmd != UCSI_CANCEL && cci & UCSI_CCI_BUSY)
167-
return ucsi_exec_command(ucsi, UCSI_CANCEL);
168-
169-
if (!(cci & UCSI_CCI_COMMAND_COMPLETE))
170-
return -EIO;
171-
172-
if (cci & UCSI_CCI_NOT_SUPPORTED) {
173-
if (ucsi_acknowledge(ucsi, false) < 0)
174-
dev_err(ucsi->dev,
175-
"ACK of unsupported command failed\n");
176-
return -EOPNOTSUPP;
177-
}
178-
179-
if (cci & UCSI_CCI_ERROR) {
180-
/* Acknowledge the command that failed */
181-
ret = ucsi_acknowledge(ucsi, false);
182-
if (ret)
183-
return ret;
184-
185-
if (cmd == UCSI_GET_ERROR_STATUS)
186-
return -EIO;
187-
188-
return ucsi_read_error(ucsi, connector_num);
189-
}
190-
191-
if (cmd == UCSI_CANCEL && cci & UCSI_CCI_CANCEL_COMPLETE) {
192-
ret = ucsi_acknowledge(ucsi, false);
193-
return ret ? ret : -EBUSY;
194-
}
195-
196-
return UCSI_CCI_LENGTH(cci);
197-
}
198-
199-
static int ucsi_send_command_common(struct ucsi *ucsi, u64 command,
200-
void *data, size_t size, bool conn_ack)
201-
{
202-
u8 length;
203-
int ret;
204-
205208
mutex_lock(&ucsi->ppm_lock);
206209

207-
ret = ucsi_exec_command(ucsi, command);
208-
if (ret < 0)
209-
goto out;
210-
211-
length = ret;
212-
213-
if (data) {
214-
ret = ucsi_read_message_in(ucsi, data, size);
215-
if (ret)
216-
goto out;
210+
ret = ucsi_run_command(ucsi, cmd, &cci, data, size, conn_ack);
211+
if (cci & UCSI_CCI_BUSY) {
212+
ret = ucsi_run_command(ucsi, UCSI_CANCEL, &cci, NULL, 0, false);
213+
return ret ? ret : -EBUSY;
217214
}
218215

219-
ret = ucsi_acknowledge(ucsi, conn_ack);
220-
if (ret)
221-
goto out;
216+
if (cci & UCSI_CCI_ERROR)
217+
return ucsi_read_error(ucsi, connector_num);
222218

223-
ret = length;
224-
out:
225219
mutex_unlock(&ucsi->ppm_lock);
226220
return ret;
227221
}

0 commit comments

Comments
 (0)