mirror of
https://github.com/apache/nuttx.git
synced 2026-06-04 06:42:32 +08:00
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:
committed by
Abdelatif Guettouche
parent
d9b42cebe7
commit
4829c3d2ab
+45
-33
@@ -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 */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user