Check return from nxsem_wait_initialize()

Resolution of Issue 619 will require multiple steps, this part of the first step in that resolution:  Every call to nxsem_wait_uninterruptible() must handle the return value from nxsem_wait_uninterruptible properly.  This commit is only for those files under drivers/input.
This commit is contained in:
Gregory Nutt
2020-03-30 16:32:20 -06:00
committed by Abdelatif Guettouche
parent d9b42cebe7
commit 4829c3d2ab
6 changed files with 324 additions and 224 deletions
+45 -33
View File
@@ -90,6 +90,7 @@
****************************************************************************/
/* Driver support ***********************************************************/
/* This format is used to construct the /dev/input[n] device driver path. It
* defined here so that it will be used consistently in all places.
*/
@@ -118,16 +119,16 @@ struct ft5x06_dev_s
* has been opened */
uint8_t nwaiters; /* Number of threads waiting for
* FT5x06 data */
volatile bool valid; /* True: New, valid touch data in
* touchbuf[] */
volatile bool valid; /* True: New, valid touch data
* in touchbuf[] */
#ifdef CONFIG_FT5X06_SINGLEPOINT
uint8_t lastid; /* Last reported touch id */
uint8_t lastevent; /* Last reported event */
int16_t lastx; /* Last reported X position */
int16_t lasty; /* Last reported Y position */
#endif
sem_t devsem; /* Manages exclusive access to this
* structure */
sem_t devsem; /* Manages exclusive access to
* this structure */
sem_t waitsem; /* Used to wait for the
* availability of data */
uint32_t frequency; /* Current I2C frequency */
@@ -137,12 +138,12 @@ struct ft5x06_dev_s
FAR const struct ft5x06_config_s *config; /* Board configuration data */
FAR struct i2c_master_s *i2c; /* Saved I2C driver instance */
struct work_s work; /* Supports the interrupt handling
* "bottom half" */
struct work_s work; /* Supports the interrupt
* handling "bottom half" */
#ifdef CONFIG_FT5X06_POLLMODE
WDOG_ID polltimer; /* Poll timer */
#endif
uint8_t touchbuf[FT5x06_TOUCH_DATA_LEN]; /* Raw touch data */
uint8_t touchbuf[FT5X06_TOUCH_DATA_LEN]; /* Raw touch data */
/* The following is a list if poll structures of threads waiting for
* driver events. The 'struct pollfd' reference for each open is also
@@ -205,10 +206,10 @@ static const struct file_operations ft5x06_fops =
static const uint8_t g_event_map[4] =
{
(TOUCH_DOWN | TOUCH_ID_VALID | TOUCH_POS_VALID), /* FT5x06_DOWN */
(TOUCH_UP | TOUCH_ID_VALID), /* FT5x06_UP */
(TOUCH_MOVE | TOUCH_ID_VALID | TOUCH_POS_VALID), /* FT5x06_CONTACT */
TOUCH_ID_VALID /* FT5x06_INVALID */
(TOUCH_DOWN | TOUCH_ID_VALID | TOUCH_POS_VALID), /* FT5X06_DOWN */
(TOUCH_UP | TOUCH_ID_VALID), /* FT5X06_UP */
(TOUCH_MOVE | TOUCH_ID_VALID | TOUCH_POS_VALID), /* FT5X06_CONTACT */
TOUCH_ID_VALID /* FT5X06_INVALID */
};
/****************************************************************************
@@ -236,10 +237,10 @@ static void ft5x06_notify(FAR struct ft5x06_dev_s *priv)
nxsem_post(&priv->waitsem);
}
/* If there are threads waiting on poll() for FT5x06 data to become available,
* then wake them up now. NOTE: we wake up all waiting threads because we
* do not know that they are going to do. If they all try to read the data,
* then some make end up blocking after all.
/* If there are threads waiting on poll() for FT5x06 data to become
* available, then wake them up now. NOTE: we wake up all waiting threads
* because we do not know that they are going to do. If they all try to
* read the data, then some make end up blocking after all.
*/
for (i = 0; i < CONFIG_FT5X06_NPOLLWAITERS; i++)
@@ -276,12 +277,23 @@ static void ft5x06_data_worker(FAR void *arg)
* corrupt any read operation that is in place.
*/
nxsem_wait_uninterruptible(&priv->devsem);
do
{
ret = nxsem_wait_uninterruptible(&priv->devsem);
/* This would only fail if something canceled the worker thread?
* That is not expected.
*/
DEBUGASSERT(ret == OK || ret == -ECANCELED);
}
while (ret < 0);
/* Read touch data */
/* Set up the address write operation */
regaddr = FT5x06_TOUCH_DATA_STARTREG;
regaddr = FT5X06_TOUCH_DATA_STARTREG;
msg[0].frequency = priv->frequency; /* I2C frequency */
msg[0].addr = config->address; /* 7-bit address */
@@ -300,7 +312,7 @@ static void ft5x06_data_worker(FAR void *arg)
msg[1].addr = config->address; /* 7-bit address */
msg[1].flags = I2C_M_READ; /* Read transaction with Re-START */
msg[1].buffer = priv->touchbuf; /* Read all touch data */
msg[1].length = FT5x06_TOUCH_DATA_LEN;
msg[1].length = FT5X06_TOUCH_DATA_LEN;
ret = I2C_TRANSFER(priv->i2c, msg, 2);
if (ret >= 0)
@@ -320,7 +332,7 @@ static void ft5x06_data_worker(FAR void *arg)
* would save a context switch.
*/
if (sample->tdstatus <= FT5x06_MAX_TOUCHES)
if (sample->tdstatus <= FT5X06_MAX_TOUCHES)
{
/* Notify any waiters that new FT5x06 data is available */
@@ -331,7 +343,7 @@ static void ft5x06_data_worker(FAR void *arg)
#ifdef CONFIG_FT5X06_POLLMODE
/* Update the poll rate */
if (sample->tdstatus > 0 && sample->tdstatus <= FT5x06_MAX_TOUCHES)
if (sample->tdstatus > 0 && sample->tdstatus <= FT5X06_MAX_TOUCHES)
{
/* Keep it at the minimum if touches are detected. */
@@ -469,9 +481,9 @@ static ssize_t ft5x06_sample(FAR struct ft5x06_dev_s *priv, FAR char *buffer,
event = TOUCH_POINT_GET_EVENT(touch[0]);
id = TOUCH_POINT_GET_ID(touch[0]);
if (event == FT5x06_INVALID)
if (event == FT5X06_INVALID)
{
priv->lastevent = FT5x06_INVALID;
priv->lastevent = FT5X06_INVALID;
goto reset_and_drop;
}
@@ -479,7 +491,7 @@ static ssize_t ft5x06_sample(FAR struct ft5x06_dev_s *priv, FAR char *buffer,
{
/* Same ID and event.. Is there positional data? */
if (raw->tdstatus == 0 || event == FT5x06_UP)
if (raw->tdstatus == 0 || event == FT5X06_UP)
{
/* No... no new touch data */
@@ -579,7 +591,7 @@ static ssize_t ft5x06_sample(FAR struct ft5x06_dev_s *priv, FAR char *buffer,
/* Decode number of touches */
ntouches = raw->tdstatus;
DEBUGASSERT(ntouches <= FT5x06_MAX_TOUCHES);
DEBUGASSERT(ntouches <= FT5X06_MAX_TOUCHES);
if (ntouches > maxtouches)
{
@@ -671,8 +683,8 @@ static ssize_t ft5x06_waitsample(FAR struct ft5x06_dev_s *priv,
}
/* Re-acquire the semaphore that manages mutually exclusive access to
* the device structure. We may have to wait here. But we have our sample.
* Interrupts and pre-emption will be re-enabled while we wait.
* the device structure. We may have to wait here. But we have our
* sample. Interrupts and pre-emption will be re-enabled while we wait.
*/
ret = nxsem_wait(&priv->devsem);
@@ -718,8 +730,8 @@ static int ft5x06_bringup(FAR struct ft5x06_dev_s *priv)
/* Set device mode to normal operation */
data[0] = FT5x06_TOUCH_MODE_REG; /* Register address */
data[1] = FT5x06_DEV_MODE_WORKING; /* Normal mode */
data[0] = FT5X06_TOUCH_MODE_REG; /* Register address */
data[1] = FT5X06_DEV_MODE_WORKING; /* Normal mode */
msg.frequency = priv->frequency; /* I2C frequency */
msg.addr = config->address; /* 7-bit address */
@@ -861,10 +873,10 @@ static int ft5x06_close(FAR struct file *filep)
* to the driver and it can be uninitialized.
*/
if (priv->crefs == 0)
{
ft5x06_shutdown(priv);
}
if (priv->crefs == 0)
{
ft5x06_shutdown(priv);
}
nxsem_post(&priv->devsem);
return OK;
@@ -923,7 +935,7 @@ static ssize_t ft5x06_read(FAR struct file *filep, FAR char *buffer,
{
ret = -EAGAIN;
goto errout;
}
}
/* Wait for sample data */