From e1c62ea4778bfd0845e2ff761a64847d36b569b3 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Tue, 27 Sep 2011 19:00:59 +0200 Subject: [PATCH] --- yaml --- r: 268576 b: refs/heads/master c: bb0590e2723eed53b524d61cf011d53fc7280949 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/drivers/staging/nvec/nvec.c | 31 +++++++++++++++++++++++++------ 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/[refs] b/[refs] index dece250591b1..2ff4720535d4 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 198dd26714ba4a60ccc5ce70bc4506613b4f0c2d +refs/heads/master: bb0590e2723eed53b524d61cf011d53fc7280949 diff --git a/trunk/drivers/staging/nvec/nvec.c b/trunk/drivers/staging/nvec/nvec.c index 488d7dd78a2f..c05adcd7fbfd 100644 --- a/trunk/drivers/staging/nvec/nvec.c +++ b/trunk/drivers/staging/nvec/nvec.c @@ -62,6 +62,16 @@ #define I2C_SL_ADDR2 0x30 #define I2C_SL_DELAY_COUNT 0x3c +/** + * enum nvec_msg_category - Message categories for nvec_msg_alloc() + * @NVEC_MSG_RX: The message is an incoming message (from EC) + * @NVEC_MSG_TX: The message is an outgoing message (to EC) + */ +enum nvec_msg_category { + NVEC_MSG_RX, + NVEC_MSG_TX, +}; + static const unsigned char EC_DISABLE_EVENT_REPORTING[3] = "\x04\x00\x00"; static const unsigned char EC_ENABLE_EVENT_REPORTING[3] = "\x04\x00\x01"; static const unsigned char EC_GET_FIRMWARE_VERSION[2] = "\x07\x15"; @@ -131,23 +141,31 @@ static int nvec_status_notifier(struct notifier_block *nb, /** * nvec_msg_alloc: * @nvec: A &struct nvec_chip + * @category: Pool category, see &enum nvec_msg_category * * Allocate a single &struct nvec_msg object from the message pool of * @nvec. The result shall be passed to nvec_msg_free() if no longer * used. + * + * Outgoing messages are placed in the upper 75% of the pool, keeping the + * lower 25% available for RX buffers only. The reason is to prevent a + * situation where all buffers are full and a message is thus endlessly + * retried because the response could never be processed. */ -static struct nvec_msg *nvec_msg_alloc(struct nvec_chip *nvec) +static struct nvec_msg *nvec_msg_alloc(struct nvec_chip *nvec, + enum nvec_msg_category category) { - int i; + int i = (category == NVEC_MSG_TX) ? (NVEC_POOL_SIZE / 4) : 0; - for (i = 0; i < NVEC_POOL_SIZE; i++) { + for (; i < NVEC_POOL_SIZE; i++) { if (atomic_xchg(&nvec->msg_pool[i].used, 1) == 0) { dev_vdbg(nvec->dev, "INFO: Allocate %i\n", i); return &nvec->msg_pool[i]; } } - dev_err(nvec->dev, "could not allocate buffer\n"); + dev_err(nvec->dev, "could not allocate %s buffer\n", + (category == NVEC_MSG_TX) ? "TX" : "RX"); return NULL; } @@ -230,7 +248,8 @@ int nvec_write_async(struct nvec_chip *nvec, const unsigned char *data, struct nvec_msg *msg; unsigned long flags; - msg = nvec_msg_alloc(nvec); + msg = nvec_msg_alloc(nvec, NVEC_MSG_TX); + if (msg == NULL) return -ENOMEM; @@ -534,7 +553,7 @@ static irqreturn_t nvec_interrupt(int irq, void *dev) if (status != I2C_SL_IRQ) { nvec_invalid_flags(nvec, status, true); } else { - nvec->rx = nvec_msg_alloc(nvec); + nvec->rx = nvec_msg_alloc(nvec, NVEC_MSG_RX); nvec->rx->data[0] = received; nvec->rx->pos = 1; nvec->state = 2;