Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge patch series "usb: typec: ucsi: revert broken buffer management"

Johan Hovold <johan@kernel.org> says:

The new buffer management code has not been tested or reviewed properly
and breaks boot of machines like the Lenovo ThinkPad X13s.

Fixing this will require designing a proper interface for managing these
transactions, something which most likely involves reverting most of the
offending commit anyway.

Revert the broken code to fix the regression and let Intel come up with
a properly tested implementation for a later kernel.

Link: https://lore.kernel.org/r/20251222152204.2846-1-johan@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

+71 -172
+3 -2
drivers/usb/typec/ucsi/cros_ec_ucsi.c
··· 105 105 return 0; 106 106 } 107 107 108 - static int cros_ucsi_sync_control(struct ucsi *ucsi, u64 cmd, u32 *cci) 108 + static int cros_ucsi_sync_control(struct ucsi *ucsi, u64 cmd, u32 *cci, 109 + void *data, size_t size) 109 110 { 110 111 struct cros_ucsi_data *udata = ucsi_get_drvdata(ucsi); 111 112 int ret; 112 113 113 - ret = ucsi_sync_control_common(ucsi, cmd, cci); 114 + ret = ucsi_sync_control_common(ucsi, cmd, cci, data, size); 114 115 switch (ret) { 115 116 case -EBUSY: 116 117 /* EC may return -EBUSY if CCI.busy is set.
+4 -32
drivers/usb/typec/ucsi/debugfs.c
··· 37 37 case UCSI_SET_USB: 38 38 case UCSI_SET_POWER_LEVEL: 39 39 case UCSI_READ_POWER_LEVEL: 40 - case UCSI_SET_PDOS: 41 - ucsi->message_in_size = 0; 42 - ret = ucsi_send_command(ucsi, val); 40 + ret = ucsi_send_command(ucsi, val, NULL, 0); 43 41 break; 44 42 case UCSI_GET_CAPABILITY: 45 43 case UCSI_GET_CONNECTOR_CAPABILITY: ··· 52 54 case UCSI_GET_ATTENTION_VDO: 53 55 case UCSI_GET_CAM_CS: 54 56 case UCSI_GET_LPM_PPM_INFO: 55 - ucsi->message_in_size = sizeof(ucsi->debugfs->response); 56 - ret = ucsi_send_command(ucsi, val); 57 - memcpy(&ucsi->debugfs->response, ucsi->message_in, sizeof(ucsi->debugfs->response)); 57 + ret = ucsi_send_command(ucsi, val, 58 + &ucsi->debugfs->response, 59 + sizeof(ucsi->debugfs->response)); 58 60 break; 59 61 default: 60 62 ret = -EOPNOTSUPP; ··· 109 111 } 110 112 DEFINE_SHOW_ATTRIBUTE(ucsi_vbus_volt); 111 113 112 - static ssize_t ucsi_message_out_write(struct file *file, 113 - const char __user *data, size_t count, loff_t *ppos) 114 - { 115 - struct ucsi *ucsi = file->private_data; 116 - int ret; 117 - 118 - char *buf __free(kfree) = memdup_user_nul(data, count); 119 - if (IS_ERR(buf)) 120 - return PTR_ERR(buf); 121 - 122 - ucsi->message_out_size = min(count / 2, UCSI_MAX_MESSAGE_OUT_LENGTH); 123 - ret = hex2bin(ucsi->message_out, buf, ucsi->message_out_size); 124 - if (ret) 125 - return ret; 126 - 127 - return count; 128 - } 129 - 130 - static const struct file_operations ucsi_message_out_fops = { 131 - .open = simple_open, 132 - .write = ucsi_message_out_write, 133 - .llseek = generic_file_llseek, 134 - }; 135 - 136 114 void ucsi_debugfs_register(struct ucsi *ucsi) 137 115 { 138 116 ucsi->debugfs = kzalloc(sizeof(*ucsi->debugfs), GFP_KERNEL); ··· 121 147 debugfs_create_file("peak_current", 0400, ucsi->debugfs->dentry, ucsi, &ucsi_peak_curr_fops); 122 148 debugfs_create_file("avg_current", 0400, ucsi->debugfs->dentry, ucsi, &ucsi_avg_curr_fops); 123 149 debugfs_create_file("vbus_voltage", 0400, ucsi->debugfs->dentry, ucsi, &ucsi_vbus_volt_fops); 124 - debugfs_create_file("message_out", 0200, ucsi->debugfs->dentry, ucsi, 125 - &ucsi_message_out_fops); 126 150 } 127 151 128 152 void ucsi_debugfs_unregister(struct ucsi *ucsi)
+3 -8
drivers/usb/typec/ucsi/displayport.c
··· 67 67 } 68 68 69 69 command = UCSI_GET_CURRENT_CAM | UCSI_CONNECTOR_NUMBER(dp->con->num); 70 - ucsi->message_in_size = sizeof(cur); 71 - ret = ucsi_send_command(ucsi, command); 70 + ret = ucsi_send_command(ucsi, command, &cur, sizeof(cur)); 72 71 if (ret < 0) { 73 72 if (ucsi->version > 0x0100) 74 73 goto err_unlock; 75 74 cur = 0xff; 76 - } else { 77 - memcpy(&cur, ucsi->message_in, ucsi->message_in_size); 78 75 } 79 76 80 77 if (cur != 0xff) { ··· 126 129 } 127 130 128 131 command = UCSI_CMD_SET_NEW_CAM(dp->con->num, 0, dp->offset, 0); 129 - dp->con->ucsi->message_in_size = 0; 130 - ret = ucsi_send_command(dp->con->ucsi, command); 132 + ret = ucsi_send_command(dp->con->ucsi, command, NULL, 0); 131 133 if (ret < 0) 132 134 goto out_unlock; 133 135 ··· 193 197 194 198 command = UCSI_CMD_SET_NEW_CAM(dp->con->num, 1, dp->offset, pins); 195 199 196 - dp->con->ucsi->message_in_size = 0; 197 - return ucsi_send_command(dp->con->ucsi, command); 200 + return ucsi_send_command(dp->con->ucsi, command, NULL, 0); 198 201 } 199 202 200 203 static int ucsi_displayport_vdm(struct typec_altmode *alt,
+36 -82
drivers/usb/typec/ucsi/ucsi.c
··· 55 55 } 56 56 EXPORT_SYMBOL_GPL(ucsi_notify_common); 57 57 58 - int ucsi_sync_control_common(struct ucsi *ucsi, u64 command, u32 *cci) 58 + int ucsi_sync_control_common(struct ucsi *ucsi, u64 command, u32 *cci, 59 + void *data, size_t size) 59 60 { 60 61 bool ack = UCSI_COMMAND(command) == UCSI_ACK_CC_CI; 61 62 int ret; ··· 67 66 set_bit(COMMAND_PENDING, &ucsi->flags); 68 67 69 68 reinit_completion(&ucsi->complete); 70 - 71 - if (ucsi->message_out_size > 0) { 72 - if (!ucsi->ops->write_message_out) { 73 - ucsi->message_out_size = 0; 74 - ret = -EOPNOTSUPP; 75 - goto out_clear_bit; 76 - } 77 - 78 - ret = ucsi->ops->write_message_out(ucsi, ucsi->message_out, 79 - ucsi->message_out_size); 80 - ucsi->message_out_size = 0; 81 - if (ret) 82 - goto out_clear_bit; 83 - } 84 69 85 70 ret = ucsi->ops->async_control(ucsi, command); 86 71 if (ret) ··· 84 97 if (!ret && cci) 85 98 ret = ucsi->ops->read_cci(ucsi, cci); 86 99 87 - if (!ret && ucsi->message_in_size > 0 && 100 + if (!ret && data && 88 101 (*cci & UCSI_CCI_COMMAND_COMPLETE)) 89 - ret = ucsi->ops->read_message_in(ucsi, ucsi->message_in, 90 - ucsi->message_in_size); 102 + ret = ucsi->ops->read_message_in(ucsi, data, size); 91 103 92 104 return ret; 93 105 } ··· 103 117 ctrl |= UCSI_ACK_CONNECTOR_CHANGE; 104 118 } 105 119 106 - ucsi->message_in_size = 0; 107 - return ucsi->ops->sync_control(ucsi, ctrl, NULL); 120 + return ucsi->ops->sync_control(ucsi, ctrl, NULL, NULL, 0); 108 121 } 109 122 110 - static int ucsi_run_command(struct ucsi *ucsi, u64 command, u32 *cci, bool conn_ack) 123 + static int ucsi_run_command(struct ucsi *ucsi, u64 command, u32 *cci, 124 + void *data, size_t size, bool conn_ack) 111 125 { 112 126 int ret, err; 113 127 114 128 *cci = 0; 115 129 116 - if (ucsi->message_in_size > UCSI_MAX_DATA_LENGTH(ucsi)) 130 + if (size > UCSI_MAX_DATA_LENGTH(ucsi)) 117 131 return -EINVAL; 118 132 119 - ret = ucsi->ops->sync_control(ucsi, command, cci); 133 + ret = ucsi->ops->sync_control(ucsi, command, cci, data, size); 120 134 121 - if (*cci & UCSI_CCI_BUSY) { 122 - ucsi->message_in_size = 0; 123 - return ucsi_run_command(ucsi, UCSI_CANCEL, cci, false) ?: -EBUSY; 124 - } 135 + if (*cci & UCSI_CCI_BUSY) 136 + return ucsi_run_command(ucsi, UCSI_CANCEL, cci, NULL, 0, false) ?: -EBUSY; 125 137 if (ret) 126 138 return ret; 127 139 ··· 151 167 int ret; 152 168 153 169 command = UCSI_GET_ERROR_STATUS | UCSI_CONNECTOR_NUMBER(connector_num); 154 - ucsi->message_in_size = sizeof(error); 155 - ret = ucsi_run_command(ucsi, command, &cci, false); 170 + ret = ucsi_run_command(ucsi, command, &cci, &error, sizeof(error), false); 156 171 if (ret < 0) 157 172 return ret; 158 - 159 - memcpy(&error, ucsi->message_in, sizeof(error)); 160 173 161 174 switch (error) { 162 175 case UCSI_ERROR_INCOMPATIBLE_PARTNER: ··· 200 219 return -EIO; 201 220 } 202 221 203 - static int ucsi_send_command_common(struct ucsi *ucsi, u64 cmd, bool conn_ack) 222 + static int ucsi_send_command_common(struct ucsi *ucsi, u64 cmd, 223 + void *data, size_t size, bool conn_ack) 204 224 { 205 225 u8 connector_num; 206 226 u32 cci; ··· 229 247 230 248 mutex_lock(&ucsi->ppm_lock); 231 249 232 - ret = ucsi_run_command(ucsi, cmd, &cci, conn_ack); 250 + ret = ucsi_run_command(ucsi, cmd, &cci, data, size, conn_ack); 233 251 234 252 if (cci & UCSI_CCI_ERROR) 235 253 ret = ucsi_read_error(ucsi, connector_num); ··· 238 256 return ret; 239 257 } 240 258 241 - int ucsi_send_command(struct ucsi *ucsi, u64 command) 259 + int ucsi_send_command(struct ucsi *ucsi, u64 command, 260 + void *data, size_t size) 242 261 { 243 - return ucsi_send_command_common(ucsi, command, false); 262 + return ucsi_send_command_common(ucsi, command, data, size, false); 244 263 } 245 264 EXPORT_SYMBOL_GPL(ucsi_send_command); 246 265 ··· 319 336 int i; 320 337 321 338 command = UCSI_GET_CURRENT_CAM | UCSI_CONNECTOR_NUMBER(con->num); 322 - con->ucsi->message_in_size = sizeof(cur); 323 - ret = ucsi_send_command(con->ucsi, command); 339 + ret = ucsi_send_command(con->ucsi, command, &cur, sizeof(cur)); 324 340 if (ret < 0) { 325 341 if (con->ucsi->version > 0x0100) { 326 342 dev_err(con->ucsi->dev, ··· 327 345 return; 328 346 } 329 347 cur = 0xff; 330 - } else { 331 - memcpy(&cur, con->ucsi->message_in, sizeof(cur)); 332 348 } 333 349 334 350 if (cur < UCSI_MAX_ALTMODES) ··· 510 530 command |= UCSI_GET_ALTMODE_RECIPIENT(recipient); 511 531 command |= UCSI_GET_ALTMODE_CONNECTOR_NUMBER(con->num); 512 532 command |= UCSI_GET_ALTMODE_OFFSET(i); 513 - ucsi->message_in_size = sizeof(alt); 514 - len = ucsi_send_command(con->ucsi, command); 533 + len = ucsi_send_command(con->ucsi, command, &alt, sizeof(alt)); 515 534 /* 516 535 * We are collecting all altmodes first and then registering. 517 536 * Some type-C device will return zero length data beyond last ··· 518 539 */ 519 540 if (len < 0) 520 541 return len; 521 - 522 - memcpy(&alt, ucsi->message_in, sizeof(alt)); 523 542 524 543 /* We got all altmodes, now break out and register them */ 525 544 if (!len || !alt.svid) ··· 586 609 command |= UCSI_GET_ALTMODE_RECIPIENT(recipient); 587 610 command |= UCSI_GET_ALTMODE_CONNECTOR_NUMBER(con->num); 588 611 command |= UCSI_GET_ALTMODE_OFFSET(i); 589 - con->ucsi->message_in_size = sizeof(alt); 590 - len = ucsi_send_command(con->ucsi, command); 612 + len = ucsi_send_command(con->ucsi, command, alt, sizeof(alt)); 591 613 if (len == -EBUSY) 592 614 continue; 593 615 if (len <= 0) 594 616 return len; 595 - 596 - memcpy(&alt, con->ucsi->message_in, sizeof(alt)); 597 617 598 618 /* 599 619 * This code is requesting one alt mode at a time, but some PPMs ··· 659 685 UCSI_MAX_DATA_LENGTH(con->ucsi)); 660 686 int ret; 661 687 662 - con->ucsi->message_in_size = size; 663 - ret = ucsi_send_command_common(con->ucsi, command, conn_ack); 664 - memcpy(&con->status, con->ucsi->message_in, size); 688 + ret = ucsi_send_command_common(con->ucsi, command, &con->status, size, conn_ack); 665 689 666 690 return ret < 0 ? ret : 0; 667 691 } ··· 682 710 command |= UCSI_GET_PDOS_PDO_OFFSET(offset); 683 711 command |= UCSI_GET_PDOS_NUM_PDOS(num_pdos - 1); 684 712 command |= is_source(role) ? UCSI_GET_PDOS_SRC_PDOS : 0; 685 - ucsi->message_in_size = num_pdos * sizeof(u32); 686 - ret = ucsi_send_command(ucsi, command); 687 - memcpy(pdos + offset, ucsi->message_in, num_pdos * sizeof(u32)); 713 + ret = ucsi_send_command(ucsi, command, pdos + offset, 714 + num_pdos * sizeof(u32)); 688 715 if (ret < 0 && ret != -ETIMEDOUT) 689 716 dev_err(ucsi->dev, "UCSI_GET_PDOS failed (%d)\n", ret); 690 717 ··· 770 799 command |= UCSI_GET_PD_MESSAGE_BYTES(len); 771 800 command |= UCSI_GET_PD_MESSAGE_TYPE(type); 772 801 773 - con->ucsi->message_in_size = len; 774 - ret = ucsi_send_command(con->ucsi, command); 775 - memcpy(data + offset, con->ucsi->message_in, len); 802 + ret = ucsi_send_command(con->ucsi, command, data + offset, len); 776 803 if (ret < 0) 777 804 return ret; 778 805 } ··· 935 966 int ret; 936 967 937 968 command = UCSI_GET_CABLE_PROPERTY | UCSI_CONNECTOR_NUMBER(con->num); 938 - con->ucsi->message_in_size = sizeof(cable_prop); 939 - ret = ucsi_send_command(con->ucsi, command); 940 - memcpy(&cable_prop, con->ucsi->message_in, sizeof(cable_prop)); 969 + ret = ucsi_send_command(con->ucsi, command, &cable_prop, sizeof(cable_prop)); 941 970 if (ret < 0) { 942 971 dev_err(con->ucsi->dev, "GET_CABLE_PROPERTY failed (%d)\n", ret); 943 972 return ret; ··· 996 1029 return 0; 997 1030 998 1031 command = UCSI_GET_CONNECTOR_CAPABILITY | UCSI_CONNECTOR_NUMBER(con->num); 999 - con->ucsi->message_in_size = sizeof(con->cap); 1000 - ret = ucsi_send_command(con->ucsi, command); 1001 - memcpy(&con->cap, con->ucsi->message_in, sizeof(con->cap)); 1032 + ret = ucsi_send_command(con->ucsi, command, &con->cap, sizeof(con->cap)); 1002 1033 if (ret < 0) { 1003 1034 dev_err(con->ucsi->dev, "GET_CONNECTOR_CAPABILITY failed (%d)\n", ret); 1004 1035 return ret; ··· 1380 1415 else if (con->ucsi->version >= UCSI_VERSION_2_0) 1381 1416 command |= hard ? 0 : UCSI_CONNECTOR_RESET_DATA_VER_2_0; 1382 1417 1383 - con->ucsi->message_in_size = 0; 1384 - return ucsi_send_command(con->ucsi, command); 1418 + return ucsi_send_command(con->ucsi, command, NULL, 0); 1385 1419 } 1386 1420 1387 1421 static int ucsi_reset_ppm(struct ucsi *ucsi) ··· 1461 1497 { 1462 1498 int ret; 1463 1499 1464 - con->ucsi->message_in_size = 0; 1465 - ret = ucsi_send_command(con->ucsi, command); 1500 + ret = ucsi_send_command(con->ucsi, command, NULL, 0); 1466 1501 if (ret == -ETIMEDOUT) { 1467 1502 u64 c; 1468 1503 ··· 1469 1506 ucsi_reset_ppm(con->ucsi); 1470 1507 1471 1508 c = UCSI_SET_NOTIFICATION_ENABLE | con->ucsi->ntfy; 1472 - con->ucsi->message_in_size = 0; 1473 - ucsi_send_command(con->ucsi, c); 1509 + ucsi_send_command(con->ucsi, c, NULL, 0); 1474 1510 1475 1511 ucsi_reset_connector(con, true); 1476 1512 } ··· 1622 1660 /* Get connector capability */ 1623 1661 command = UCSI_GET_CONNECTOR_CAPABILITY; 1624 1662 command |= UCSI_CONNECTOR_NUMBER(con->num); 1625 - ucsi->message_in_size = sizeof(con->cap); 1626 - ret = ucsi_send_command(ucsi, command); 1663 + ret = ucsi_send_command(ucsi, command, &con->cap, sizeof(con->cap)); 1627 1664 if (ret < 0) 1628 1665 goto out_unlock; 1629 - 1630 - memcpy(&con->cap, ucsi->message_in, sizeof(con->cap)); 1631 1666 1632 1667 if (UCSI_CONCAP(con, OPMODE_DRP)) 1633 1668 cap->data = TYPEC_PORT_DRD; ··· 1822 1863 /* Enable basic notifications */ 1823 1864 ntfy = UCSI_ENABLE_NTFY_CMD_COMPLETE | UCSI_ENABLE_NTFY_ERROR; 1824 1865 command = UCSI_SET_NOTIFICATION_ENABLE | ntfy; 1825 - ucsi->message_in_size = 0; 1826 - ret = ucsi_send_command(ucsi, command); 1866 + ret = ucsi_send_command(ucsi, command, NULL, 0); 1827 1867 if (ret < 0) 1828 1868 goto err_reset; 1829 1869 1830 1870 /* Get PPM capabilities */ 1831 1871 command = UCSI_GET_CAPABILITY; 1832 - ucsi->message_in_size = BITS_TO_BYTES(UCSI_GET_CAPABILITY_SIZE); 1833 - ret = ucsi_send_command(ucsi, command); 1872 + ret = ucsi_send_command(ucsi, command, &ucsi->cap, 1873 + BITS_TO_BYTES(UCSI_GET_CAPABILITY_SIZE)); 1834 1874 if (ret < 0) 1835 1875 goto err_reset; 1836 - 1837 - memcpy(&ucsi->cap, ucsi->message_in, BITS_TO_BYTES(UCSI_GET_CAPABILITY_SIZE)); 1838 1876 1839 1877 if (!ucsi->cap.num_connectors) { 1840 1878 ret = -ENODEV; ··· 1862 1906 /* Enable all supported notifications */ 1863 1907 ntfy = ucsi_get_supported_notifications(ucsi); 1864 1908 command = UCSI_SET_NOTIFICATION_ENABLE | ntfy; 1865 - ucsi->message_in_size = 0; 1866 - ret = ucsi_send_command(ucsi, command); 1909 + ret = ucsi_send_command(ucsi, command, NULL, 0); 1867 1910 if (ret < 0) 1868 1911 goto err_unregister; 1869 1912 ··· 1913 1958 1914 1959 /* Restore UCSI notification enable mask after system resume */ 1915 1960 command = UCSI_SET_NOTIFICATION_ENABLE | ucsi->ntfy; 1916 - ucsi->message_in_size = 0; 1917 - ret = ucsi_send_command(ucsi, command); 1961 + ret = ucsi_send_command(ucsi, command, NULL, 0); 1918 1962 if (ret < 0) { 1919 1963 dev_err(ucsi->dev, "failed to re-enable notifications (%d)\n", ret); 1920 1964 return;
+6 -16
drivers/usb/typec/ucsi/ucsi.h
··· 29 29 #define UCSI_MESSAGE_OUT 32 30 30 #define UCSIv2_MESSAGE_OUT 272 31 31 32 - /* Define maximum lengths for message buffers */ 33 - #define UCSI_MAX_MESSAGE_IN_LENGTH 256 34 - #define UCSI_MAX_MESSAGE_OUT_LENGTH 256 35 - 36 32 /* UCSI versions */ 37 33 #define UCSI_VERSION_1_0 0x0100 38 34 #define UCSI_VERSION_1_1 0x0110 ··· 65 69 * @read_cci: Read CCI register 66 70 * @poll_cci: Read CCI register while polling with notifications disabled 67 71 * @read_message_in: Read message data from UCSI 68 - * @write_message_out: Write message data to UCSI 69 72 * @sync_control: Blocking control operation 70 73 * @async_control: Non-blocking control operation 71 74 * @update_altmodes: Squashes duplicate DP altmodes ··· 80 85 int (*read_cci)(struct ucsi *ucsi, u32 *cci); 81 86 int (*poll_cci)(struct ucsi *ucsi, u32 *cci); 82 87 int (*read_message_in)(struct ucsi *ucsi, void *val, size_t val_len); 83 - int (*write_message_out)(struct ucsi *ucsi, void *data, size_t data_len); 84 - int (*sync_control)(struct ucsi *ucsi, u64 command, u32 *cci); 88 + int (*sync_control)(struct ucsi *ucsi, u64 command, u32 *cci, 89 + void *data, size_t size); 85 90 int (*async_control)(struct ucsi *ucsi, u64 command); 86 91 bool (*update_altmodes)(struct ucsi *ucsi, u8 recipient, 87 92 struct ucsi_altmode *orig, ··· 132 137 #define UCSI_GET_PD_MESSAGE 0x15 133 138 #define UCSI_GET_CAM_CS 0x18 134 139 #define UCSI_SET_SINK_PATH 0x1c 135 - #define UCSI_SET_PDOS 0x1d 136 140 #define UCSI_READ_POWER_LEVEL 0x1e 137 141 #define UCSI_SET_USB 0x21 138 142 #define UCSI_GET_LPM_PPM_INFO 0x22 ··· 493 499 unsigned long quirks; 494 500 #define UCSI_NO_PARTNER_PDOS BIT(0) /* Don't read partner's PDOs */ 495 501 #define UCSI_DELAY_DEVICE_PDOS BIT(1) /* Reading PDOs fails until the parter is in PD mode */ 496 - 497 - /* Fixed-size buffers for incoming and outgoing messages */ 498 - u8 message_in[UCSI_MAX_MESSAGE_IN_LENGTH]; 499 - size_t message_in_size; 500 - u8 message_out[UCSI_MAX_MESSAGE_OUT_LENGTH]; 501 - size_t message_out_size; 502 502 }; 503 503 504 504 #define UCSI_MAX_DATA_LENGTH(u) (((u)->version < UCSI_VERSION_2_0) ? 0x10 : 0xff) ··· 555 567 struct usb_pd_identity cable_identity; 556 568 }; 557 569 558 - int ucsi_send_command(struct ucsi *ucsi, u64 command); 570 + int ucsi_send_command(struct ucsi *ucsi, u64 command, 571 + void *retval, size_t size); 559 572 560 573 void ucsi_altmode_update_active(struct ucsi_connector *con); 561 574 int ucsi_resume(struct ucsi *ucsi); 562 575 563 576 void ucsi_notify_common(struct ucsi *ucsi, u32 cci); 564 - int ucsi_sync_control_common(struct ucsi *ucsi, u64 command, u32 *cci); 577 + int ucsi_sync_control_common(struct ucsi *ucsi, u64 command, u32 *cci, 578 + void *data, size_t size); 565 579 566 580 #if IS_ENABLED(CONFIG_POWER_SUPPLY) 567 581 int ucsi_register_port_psy(struct ucsi_connector *con);
+5 -20
drivers/usb/typec/ucsi/ucsi_acpi.c
··· 86 86 return 0; 87 87 } 88 88 89 - static int ucsi_acpi_write_message_out(struct ucsi *ucsi, void *data, size_t data_len) 90 - { 91 - struct ucsi_acpi *ua = ucsi_get_drvdata(ucsi); 92 - 93 - if (!data || !data_len) 94 - return -EINVAL; 95 - 96 - if (ucsi->version <= UCSI_VERSION_1_2) 97 - memcpy(ua->base + UCSI_MESSAGE_OUT, data, data_len); 98 - else 99 - memcpy(ua->base + UCSIv2_MESSAGE_OUT, data, data_len); 100 - 101 - return 0; 102 - } 103 - 104 89 static int ucsi_acpi_async_control(struct ucsi *ucsi, u64 command) 105 90 { 106 91 struct ucsi_acpi *ua = ucsi_get_drvdata(ucsi); ··· 101 116 .read_cci = ucsi_acpi_read_cci, 102 117 .poll_cci = ucsi_acpi_poll_cci, 103 118 .read_message_in = ucsi_acpi_read_message_in, 104 - .write_message_out = ucsi_acpi_write_message_out, 105 119 .sync_control = ucsi_sync_control_common, 106 120 .async_control = ucsi_acpi_async_control 107 121 }; 108 122 109 - static int ucsi_gram_sync_control(struct ucsi *ucsi, u64 command, u32 *cci) 123 + static int ucsi_gram_sync_control(struct ucsi *ucsi, u64 command, u32 *cci, 124 + void *val, size_t len) 110 125 { 111 126 u16 bogus_change = UCSI_CONSTAT_POWER_LEVEL_CHANGE | 112 127 UCSI_CONSTAT_PDOS_CHANGE; 113 128 struct ucsi_acpi *ua = ucsi_get_drvdata(ucsi); 114 129 int ret; 115 130 116 - ret = ucsi_sync_control_common(ucsi, command, cci); 131 + ret = ucsi_sync_control_common(ucsi, command, cci, val, len); 117 132 if (ret < 0) 118 133 return ret; 119 134 ··· 125 140 if (UCSI_COMMAND(ua->cmd) == UCSI_GET_CONNECTOR_STATUS && 126 141 ua->check_bogus_event) { 127 142 /* Clear the bogus change */ 128 - if (*(u16 *)ucsi->message_in == bogus_change) 129 - *(u16 *)ucsi->message_in = 0; 143 + if (*(u16 *)val == bogus_change) 144 + *(u16 *)val = 0; 130 145 131 146 ua->check_bogus_event = false; 132 147 }
+6 -5
drivers/usb/typec/ucsi/ucsi_ccg.c
··· 606 606 return ccg_write(uc, reg, (u8 *)&command, sizeof(command)); 607 607 } 608 608 609 - static int ucsi_ccg_sync_control(struct ucsi *ucsi, u64 command, u32 *cci) 609 + static int ucsi_ccg_sync_control(struct ucsi *ucsi, u64 command, u32 *cci, 610 + void *data, size_t size) 610 611 { 611 612 struct ucsi_ccg *uc = ucsi_get_drvdata(ucsi); 612 613 struct ucsi_connector *con; ··· 629 628 ucsi_ccg_update_set_new_cam_cmd(uc, con, &command); 630 629 } 631 630 632 - ret = ucsi_sync_control_common(ucsi, command, cci); 631 + ret = ucsi_sync_control_common(ucsi, command, cci, data, size); 633 632 634 633 switch (UCSI_COMMAND(command)) { 635 634 case UCSI_GET_CURRENT_CAM: 636 635 if (uc->has_multiple_dp) 637 - ucsi_ccg_update_get_current_cam_cmd(uc, (u8 *)ucsi->message_in); 636 + ucsi_ccg_update_get_current_cam_cmd(uc, (u8 *)data); 638 637 break; 639 638 case UCSI_GET_ALTERNATE_MODES: 640 639 if (UCSI_ALTMODE_RECIPIENT(command) == UCSI_RECIPIENT_SOP) { 641 - struct ucsi_altmode *alt = (struct ucsi_altmode *)ucsi->message_in; 640 + struct ucsi_altmode *alt = data; 642 641 643 642 if (alt[0].svid == USB_TYPEC_NVIDIA_VLINK_SID) 644 643 ucsi_ccg_nvidia_altmode(uc, alt, command); ··· 646 645 break; 647 646 case UCSI_GET_CAPABILITY: 648 647 if (uc->fw_build == CCG_FW_BUILD_NVIDIA_TEGRA) { 649 - struct ucsi_capability *cap = (struct ucsi_capability *)ucsi->message_in; 648 + struct ucsi_capability *cap = data; 650 649 651 650 cap->features &= ~UCSI_CAP_ALT_MODE_DETAILS; 652 651 }
+8 -7
drivers/usb/typec/ucsi/ucsi_yoga_c630.c
··· 88 88 89 89 static int yoga_c630_ucsi_sync_control(struct ucsi *ucsi, 90 90 u64 command, 91 - u32 *cci) 91 + u32 *cci, 92 + void *data, size_t size) 92 93 { 93 94 int ret; 94 95 ··· 107 106 }; 108 107 109 108 dev_dbg(ucsi->dev, "faking DP altmode for con1\n"); 110 - memset(ucsi->message_in, 0, ucsi->message_in_size); 111 - memcpy(ucsi->message_in, &alt, min(sizeof(alt), ucsi->message_in_size)); 109 + memset(data, 0, size); 110 + memcpy(data, &alt, min(sizeof(alt), size)); 112 111 *cci = UCSI_CCI_COMMAND_COMPLETE | UCSI_SET_CCI_LENGTH(sizeof(alt)); 113 112 return 0; 114 113 } ··· 121 120 if (UCSI_COMMAND(command) == UCSI_GET_ALTERNATE_MODES && 122 121 UCSI_GET_ALTMODE_GET_CONNECTOR_NUMBER(command) == 2) { 123 122 dev_dbg(ucsi->dev, "ignoring altmodes for con2\n"); 124 - memset(ucsi->message_in, 0, ucsi->message_in_size); 123 + memset(data, 0, size); 125 124 *cci = UCSI_CCI_COMMAND_COMPLETE; 126 125 return 0; 127 126 } 128 127 129 - ret = ucsi_sync_control_common(ucsi, command, cci); 128 + ret = ucsi_sync_control_common(ucsi, command, cci, data, size); 130 129 if (ret < 0) 131 130 return ret; 132 131 133 132 /* UCSI_GET_CURRENT_CAM is off-by-one on all ports */ 134 - if (UCSI_COMMAND(command) == UCSI_GET_CURRENT_CAM && ucsi->message_in_size > 0) 135 - ucsi->message_in[0]--; 133 + if (UCSI_COMMAND(command) == UCSI_GET_CURRENT_CAM && data) 134 + ((u8 *)data)[0]--; 136 135 137 136 return ret; 138 137 }