diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index 79e200d71652..ca917b84ca5e 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c @@ -1556,8 +1556,8 @@ int mei_cl_irq_write(struct mei_cl *cl, struct mei_cl_cb *cb, struct mei_msg_data *buf; struct mei_msg_hdr mei_hdr; size_t len; - u32 msg_slots; - int slots; + size_t hbuf_len; + int hbuf_slots; int rets; bool first_chunk; @@ -1579,29 +1579,30 @@ int mei_cl_irq_write(struct mei_cl *cl, struct mei_cl_cb *cb, return 0; } - slots = mei_hbuf_empty_slots(dev); - if (slots < 0) - return -EOVERFLOW; - - len = buf->size - cb->buf_idx; - msg_slots = mei_data2slots(len); - mei_hdr.host_addr = mei_cl_host_addr(cl); mei_hdr.me_addr = mei_cl_me_id(cl); mei_hdr.reserved = 0; + mei_hdr.msg_complete = 0; mei_hdr.internal = cb->internal; - if ((u32)slots >= msg_slots) { + len = buf->size - cb->buf_idx; + hbuf_slots = mei_hbuf_empty_slots(dev); + if (hbuf_slots < 0) { + rets = -EOVERFLOW; + goto err; + } + hbuf_len = mei_slots2data(hbuf_slots) - sizeof(struct mei_msg_hdr); + + /** + * Split the message only if we can write the whole host buffer + * otherwise wait for next time the host buffer is empty. + */ + if (hbuf_len >= len) { mei_hdr.length = len; mei_hdr.msg_complete = 1; - /* Split the message only if we can write the whole host buffer */ - } else if ((u32)slots == dev->hbuf_depth) { - msg_slots = slots; - len = mei_slots2data(slots) - sizeof(struct mei_msg_hdr); - mei_hdr.length = len; - mei_hdr.msg_complete = 0; + } else if ((u32)hbuf_slots == mei_hbuf_depth(dev)) { + mei_hdr.length = hbuf_len; } else { - /* wait for next time the host buffer is empty */ return 0; } @@ -1650,6 +1651,8 @@ ssize_t mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb) struct mei_msg_data *buf; struct mei_msg_hdr mei_hdr; size_t len; + size_t hbuf_len; + int hbuf_slots; ssize_t rets; bool blocking; @@ -1692,19 +1695,25 @@ ssize_t mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb) rets = len; goto out; } + if (!mei_hbuf_acquire(dev)) { cl_dbg(dev, cl, "Cannot acquire the host buffer: not sending.\n"); rets = len; goto out; } - /* Check for a maximum length */ - if (len > mei_hbuf_max_len(dev)) { - mei_hdr.length = mei_hbuf_max_len(dev); - mei_hdr.msg_complete = 0; - } else { + hbuf_slots = mei_hbuf_empty_slots(dev); + if (hbuf_slots < 0) { + rets = -EOVERFLOW; + goto out; + } + + hbuf_len = mei_slots2data(hbuf_slots) - sizeof(struct mei_msg_hdr); + if (hbuf_len >= len) { mei_hdr.length = len; mei_hdr.msg_complete = 1; + } else { + mei_hdr.length = hbuf_len; } rets = mei_write_message(dev, &mei_hdr, buf->data); diff --git a/drivers/misc/mei/hw-me.c b/drivers/misc/mei/hw-me.c index 016b7c956f18..c50671cf47eb 100644 --- a/drivers/misc/mei/hw-me.c +++ b/drivers/misc/mei/hw-me.c @@ -228,7 +228,7 @@ static void mei_me_hw_config(struct mei_device *dev) /* Doesn't change in runtime */ hcsr = mei_hcsr_read(dev); - dev->hbuf_depth = (hcsr & H_CBD) >> 24; + hw->hbuf_depth = (hcsr & H_CBD) >> 24; reg = 0; pci_read_config_dword(pdev, PCI_CFG_HFS_1, ®); @@ -490,28 +490,31 @@ static bool mei_me_hbuf_is_empty(struct mei_device *dev) */ static int mei_me_hbuf_empty_slots(struct mei_device *dev) { + struct mei_me_hw *hw = to_me_hw(dev); unsigned char filled_slots, empty_slots; filled_slots = mei_hbuf_filled_slots(dev); - empty_slots = dev->hbuf_depth - filled_slots; + empty_slots = hw->hbuf_depth - filled_slots; /* check for overflow */ - if (filled_slots > dev->hbuf_depth) + if (filled_slots > hw->hbuf_depth) return -EOVERFLOW; return empty_slots; } /** - * mei_me_hbuf_max_len - returns size of hw buffer. + * mei_me_hbuf_depth - returns depth of the hw buffer. * * @dev: the device structure * - * Return: size of hw buffer in bytes + * Return: size of hw buffer in slots */ -static size_t mei_me_hbuf_max_len(const struct mei_device *dev) +static u32 mei_me_hbuf_depth(const struct mei_device *dev) { - return mei_slots2data(dev->hbuf_depth) - sizeof(struct mei_msg_hdr); + struct mei_me_hw *hw = to_me_hw(dev); + + return hw->hbuf_depth; } @@ -1317,7 +1320,7 @@ static const struct mei_hw_ops mei_me_hw_ops = { .hbuf_free_slots = mei_me_hbuf_empty_slots, .hbuf_is_ready = mei_me_hbuf_is_empty, - .hbuf_max_len = mei_me_hbuf_max_len, + .hbuf_depth = mei_me_hbuf_depth, .write = mei_me_hbuf_write, diff --git a/drivers/misc/mei/hw-me.h b/drivers/misc/mei/hw-me.h index 67892533576e..0c6fe71d1212 100644 --- a/drivers/misc/mei/hw-me.h +++ b/drivers/misc/mei/hw-me.h @@ -52,12 +52,14 @@ struct mei_cfg { * @mem_addr: io memory address * @pg_state: power gating state * @d0i3_supported: di03 support + * @hbuf_depth: depth of hardware host/write buffer in slots */ struct mei_me_hw { const struct mei_cfg *cfg; void __iomem *mem_addr; enum mei_pg_state pg_state; bool d0i3_supported; + u8 hbuf_depth; }; #define to_me_hw(dev) (struct mei_me_hw *)((dev)->hw) diff --git a/drivers/misc/mei/hw-txe.c b/drivers/misc/mei/hw-txe.c index 0facd823634e..7e2026894e9f 100644 --- a/drivers/misc/mei/hw-txe.c +++ b/drivers/misc/mei/hw-txe.c @@ -31,6 +31,7 @@ #include "mei-trace.h" +#define TXE_HBUF_DEPTH (PAYLOAD_SIZE / MEI_SLOT_SIZE) /** * mei_txe_reg_read - Reads 32bit data from the txe device @@ -681,9 +682,6 @@ static void mei_txe_hw_config(struct mei_device *dev) struct mei_txe_hw *hw = to_txe_hw(dev); - /* Doesn't change in runtime */ - dev->hbuf_depth = PAYLOAD_SIZE / MEI_SLOT_SIZE; - hw->aliveness = mei_txe_aliveness_get(dev); hw->readiness = mei_txe_readiness_get(dev); @@ -710,7 +708,7 @@ static int mei_txe_write(struct mei_device *dev, unsigned long rem; unsigned long length; unsigned long i; - u32 slots = dev->hbuf_depth; + u32 slots = TXE_HBUF_DEPTH; u32 *reg_buf = (u32 *)buf; u32 dw_cnt; @@ -762,15 +760,15 @@ static int mei_txe_write(struct mei_device *dev, } /** - * mei_txe_hbuf_max_len - mimics the me hbuf circular buffer + * mei_txe_hbuf_depth - mimics the me hbuf circular buffer * * @dev: the device structure * - * Return: the PAYLOAD_SIZE - header size + * Return: the TXE_HBUF_DEPTH */ -static size_t mei_txe_hbuf_max_len(const struct mei_device *dev) +static u32 mei_txe_hbuf_depth(const struct mei_device *dev) { - return PAYLOAD_SIZE - sizeof(struct mei_msg_hdr); + return TXE_HBUF_DEPTH; } /** @@ -778,7 +776,7 @@ static size_t mei_txe_hbuf_max_len(const struct mei_device *dev) * * @dev: the device structure * - * Return: always hbuf_depth + * Return: always TXE_HBUF_DEPTH */ static int mei_txe_hbuf_empty_slots(struct mei_device *dev) { @@ -797,7 +795,7 @@ static int mei_txe_hbuf_empty_slots(struct mei_device *dev) static int mei_txe_count_full_read_slots(struct mei_device *dev) { /* read buffers has static size */ - return PAYLOAD_SIZE / MEI_SLOT_SIZE; + return TXE_HBUF_DEPTH; } /** @@ -1140,7 +1138,7 @@ irqreturn_t mei_txe_irq_thread_handler(int irq, void *dev_id) /* Input Ready: Detection if host can write to SeC */ if (test_and_clear_bit(TXE_INTR_IN_READY_BIT, &hw->intr_cause)) { dev->hbuf_is_ready = true; - hw->slots = dev->hbuf_depth; + hw->slots = TXE_HBUF_DEPTH; } if (hw->aliveness && dev->hbuf_is_ready) { @@ -1186,7 +1184,7 @@ static const struct mei_hw_ops mei_txe_hw_ops = { .hbuf_free_slots = mei_txe_hbuf_empty_slots, .hbuf_is_ready = mei_txe_is_input_ready, - .hbuf_max_len = mei_txe_hbuf_max_len, + .hbuf_depth = mei_txe_hbuf_depth, .write = mei_txe_write, diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index 897126dca5d0..fa543dcfc111 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -29,7 +29,6 @@ #define MEI_SLOT_SIZE sizeof(u32) #define MEI_RD_MSG_BUF_SIZE (128 * MEI_SLOT_SIZE) - /* * Number of Maximum MEI Clients */ @@ -271,7 +270,7 @@ struct mei_cl { * * @hbuf_free_slots : query for write buffer empty slots * @hbuf_is_ready : query if write buffer is empty - * @hbuf_max_len : query for write buffer max len + * @hbuf_depth : query for write buffer depth * * @write : write a message to FW * @@ -301,7 +300,7 @@ struct mei_hw_ops { int (*hbuf_free_slots)(struct mei_device *dev); bool (*hbuf_is_ready)(struct mei_device *dev); - size_t (*hbuf_max_len)(const struct mei_device *dev); + u32 (*hbuf_depth)(const struct mei_device *dev); int (*write)(struct mei_device *dev, struct mei_msg_hdr *hdr, const unsigned char *buf); @@ -411,7 +410,6 @@ struct mei_fw_version { * @rd_msg_buf : control messages buffer * @rd_msg_hdr : read message header storage * - * @hbuf_depth : depth of hardware host/write buffer is slots * @hbuf_is_ready : query if the host host/write buffer is ready * * @version : HBM protocol version in use @@ -489,7 +487,6 @@ struct mei_device { u32 rd_msg_hdr; /* write buffer */ - u8 hbuf_depth; bool hbuf_is_ready; struct hbm_version version; @@ -655,9 +652,9 @@ static inline int mei_hbuf_empty_slots(struct mei_device *dev) return dev->ops->hbuf_free_slots(dev); } -static inline size_t mei_hbuf_max_len(const struct mei_device *dev) +static inline u32 mei_hbuf_depth(const struct mei_device *dev) { - return dev->ops->hbuf_max_len(dev); + return dev->ops->hbuf_depth(dev); } static inline int mei_write_message(struct mei_device *dev,