On Wed, Aug 27, 2025 at 01:12:41PM -0700, Anjelique Melendez wrote: > UCSI v2 specification has increased the MSG_IN and MSG_OUT size from > 16 bytes to 256 bytes each for the message exchange between OPM and PPM > This makes the total buffer size increase from 48 bytes to 528 bytes. > Update the buffer size to support this increase. > > Signed-off-by: Anjelique Melendez <anjelique.melendez@xxxxxxxxxxxxxxxx> > --- > drivers/usb/typec/ucsi/ucsi_glink.c | 85 +++++++++++++++++++++++++---- > 1 file changed, 75 insertions(+), 10 deletions(-) > > diff --git a/drivers/usb/typec/ucsi/ucsi_glink.c b/drivers/usb/typec/ucsi/ucsi_glink.c > index 1f9f0d942c1a..fc12569ec520 100644 > --- a/drivers/usb/typec/ucsi/ucsi_glink.c > +++ b/drivers/usb/typec/ucsi/ucsi_glink.c > @@ -16,10 +16,10 @@ > > #define PMIC_GLINK_MAX_PORTS 3 > > -#define UCSI_BUF_SIZE 48 > +#define UCSI_BUF_V1_SIZE (UCSI_MESSAGE_OUT + (UCSI_MESSAGE_OUT - UCSI_MESSAGE_IN)) > +#define UCSI_BUF_V2_SIZE (UCSIv2_MESSAGE_OUT + (UCSIv2_MESSAGE_OUT - UCSI_MESSAGE_IN)) > > #define MSG_TYPE_REQ_RESP 1 > -#define UCSI_BUF_SIZE 48 > > #define UC_NOTIFY_RECEIVER_UCSI 0x0 > #define UC_UCSI_READ_BUF_REQ 0x11 > @@ -32,13 +32,25 @@ struct ucsi_read_buf_req_msg { > > struct __packed ucsi_read_buf_resp_msg { > struct pmic_glink_hdr hdr; > - u8 buf[UCSI_BUF_SIZE]; > + u8 buf[UCSI_BUF_V1_SIZE]; > + u32 ret_code; > +}; > + > +struct __packed ucsi_v2_read_buf_resp_msg { > + struct pmic_glink_hdr hdr; > + u8 buf[UCSI_BUF_V2_SIZE]; > u32 ret_code; > }; Couldn't you just make a union inside that original struct ucsi_read_buf_resp_msg? > struct __packed ucsi_write_buf_req_msg { > struct pmic_glink_hdr hdr; > - u8 buf[UCSI_BUF_SIZE]; > + u8 buf[UCSI_BUF_V1_SIZE]; > + u32 reserved; > +}; > + > +struct __packed ucsi_v2_write_buf_req_msg { > + struct pmic_glink_hdr hdr; > + u8 buf[UCSI_BUF_V2_SIZE]; > u32 reserved; > }; Ditto for the ucsi_write_buf_req_msg. > @@ -72,7 +84,7 @@ struct pmic_glink_ucsi { > bool ucsi_registered; > bool pd_running; > > - u8 read_buf[UCSI_BUF_SIZE]; > + u8 read_buf[UCSI_BUF_V2_SIZE]; > }; > > static int pmic_glink_ucsi_read(struct ucsi *__ucsi, unsigned int offset, > @@ -131,18 +143,34 @@ static int pmic_glink_ucsi_read_message_in(struct ucsi *ucsi, void *val, size_t > static int pmic_glink_ucsi_locked_write(struct pmic_glink_ucsi *ucsi, unsigned int offset, > const void *val, size_t val_len) > { > - struct ucsi_write_buf_req_msg req = {}; > + struct ucsi_v2_write_buf_req_msg req = {}; > + size_t len, max_buf_len; > unsigned long left; > int ret; > > req.hdr.owner = PMIC_GLINK_OWNER_USBC; > req.hdr.type = MSG_TYPE_REQ_RESP; > req.hdr.opcode = UC_UCSI_WRITE_BUF_REQ; > + > + if (ucsi->ucsi->version >= UCSI_VERSION_2_0) { > + max_buf_len = UCSI_BUF_V2_SIZE; > + len = sizeof(req); > + } else if (ucsi->ucsi->version) { > + max_buf_len = UCSI_BUF_V1_SIZE; > + len = sizeof(struct ucsi_write_buf_req_msg); > + } else { > + dev_err(ucsi->dev, "UCSI version not set\n"); > + return -EINVAL; > + } > + > + if (offset + val_len > max_buf_len) > + return -EINVAL; > + > memcpy(&req.buf[offset], val, val_len); > > reinit_completion(&ucsi->write_ack); > > - ret = pmic_glink_send(ucsi->client, &req, sizeof(req)); > + ret = pmic_glink_send(ucsi->client, &req, len); > if (ret < 0) { > dev_err(ucsi->dev, "failed to send UCSI write request: %d\n", ret); > return ret; > @@ -216,12 +244,49 @@ static const struct ucsi_operations pmic_glink_ucsi_ops = { > > static void pmic_glink_ucsi_read_ack(struct pmic_glink_ucsi *ucsi, const void *data, int len) > { > - const struct ucsi_read_buf_resp_msg *resp = data; > + u32 ret_code, buf_len, max_len; > + u8 *buf; > + > + if (ucsi->ucsi->version) { > + if (ucsi->ucsi->version >= UCSI_VERSION_2_0) { > + max_len = sizeof(struct ucsi_v2_read_buf_resp_msg); > + buf = ((struct ucsi_v2_read_buf_resp_msg *)data)->buf; > + buf_len = UCSI_BUF_V2_SIZE; > + } else { > + max_len = sizeof(struct ucsi_read_buf_resp_msg); > + buf = ((struct ucsi_read_buf_resp_msg *)data)->buf; > + buf_len = UCSI_BUF_V1_SIZE; > + } > + } else if (!ucsi->ucsi->version && !ucsi->ucsi_registered) { ucsi->ucsi->version will never be set in this else condition, so no need to check it, no? > + /* > + * If UCSI version is not known yet because device is not registered, choose buffer > + * size which best fits incoming data > + */ > + if (len > sizeof(struct pmic_glink_hdr) + UCSI_BUF_V2_SIZE) { > + max_len = sizeof(struct ucsi_v2_read_buf_resp_msg); > + buf = ((struct ucsi_v2_read_buf_resp_msg *)data)->buf; > + buf_len = UCSI_BUF_V2_SIZE; > + } else { > + max_len = sizeof(struct ucsi_read_buf_resp_msg); > + buf = ((struct ucsi_read_buf_resp_msg *)data)->buf; > + buf_len = UCSI_BUF_V1_SIZE; > + } > + } else { > + dev_err(ucsi->dev, "UCSI version not set\n"); > + return; > + } I don't really see when you could enter that else statement? > - if (resp->ret_code) > + if (len > max_len) > + return; > + > + if (buf_len > len - sizeof(struct pmic_glink_hdr) - sizeof(u32)) > + buf_len = len - sizeof(struct pmic_glink_hdr) - sizeof(u32); > + > + memcpy(&ret_code, buf + sizeof(struct pmic_glink_hdr) + buf_len, sizeof(u32)); > + if (ret_code) > return; > > - memcpy(ucsi->read_buf, resp->buf, UCSI_BUF_SIZE); > + memcpy(ucsi->read_buf, buf, buf_len); > complete(&ucsi->read_ack); > } thanks, -- heikki