]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
usb: typec: ucsi: reorder operations in ucsi_run_command()
authorDmitry Baryshkov <dmitry.baryshkov@linaro.org>
Thu, 27 Jun 2024 14:44:46 +0000 (17:44 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 3 Jul 2024 14:04:50 +0000 (16:04 +0200)
Streamline control stream of ucsi_run_command(). Reorder operations so
that there is only one call to ucsi_acknowledge(), making sure that all
complete commands are acknowledged. This also makes sure that the
command is acknowledged even if reading MESSAGE_IN data returns an
error.

Tested-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Link: https://lore.kernel.org/r/20240627-ucsi-rework-interface-v4-7-289ddc6874c7@linaro.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/typec/ucsi/ucsi.c

index 25d2ee5ee8bb067d3df25555887d34cf2ad3c9d3..dcd3765cc1f532242af91ad1af5389b63adb87f0 100644 (file)
@@ -95,7 +95,7 @@ static int ucsi_acknowledge(struct ucsi *ucsi, bool conn_ack)
 static int ucsi_run_command(struct ucsi *ucsi, u64 command, u32 *cci,
                            void *data, size_t size, bool conn_ack)
 {
-       int ret;
+       int ret, err;
 
        *cci = 0;
 
@@ -120,30 +120,24 @@ static int ucsi_run_command(struct ucsi *ucsi, u64 command, u32 *cci,
        if (!(*cci & UCSI_CCI_COMMAND_COMPLETE))
                return -EIO;
 
-       if (*cci & UCSI_CCI_NOT_SUPPORTED) {
-               if (ucsi_acknowledge(ucsi, false) < 0)
-                       dev_err(ucsi->dev,
-                               "ACK of unsupported command failed\n");
-               return -EOPNOTSUPP;
-       }
-
-       if (*cci & UCSI_CCI_ERROR) {
-               /* Acknowledge the command that failed */
-               ret = ucsi_acknowledge(ucsi, false);
-               return ret ? ret : -EIO;
-       }
+       if (*cci & UCSI_CCI_NOT_SUPPORTED)
+               err = -EOPNOTSUPP;
+       else if (*cci & UCSI_CCI_ERROR)
+               err = -EIO;
+       else
+               err = 0;
 
-       if (data) {
-               ret = ucsi->ops->read_message_in(ucsi, data, size);
-               if (ret)
-                       return ret;
-       }
+       if (!err && data && UCSI_CCI_LENGTH(*cci))
+               err = ucsi->ops->read_message_in(ucsi, data, size);
 
-       ret = ucsi_acknowledge(ucsi, conn_ack);
+       /*
+        * Don't ACK connection change if there was an error.
+        */
+       ret = ucsi_acknowledge(ucsi, err ? false : conn_ack);
        if (ret)
                return ret;
 
-       return 0;
+       return err;
 }
 
 static int ucsi_read_error(struct ucsi *ucsi, u8 connector_num)