Skip to content

Commit

Permalink
Check return from nxsem_wait_initialize()
Browse files Browse the repository at this point in the history
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/audio, drivers/net, and drivers/lcd.
  • Loading branch information
gregory-nutt authored and Ouss4 committed Mar 31, 2020
1 parent 7f510a6 commit 5b74974
Show file tree
Hide file tree
Showing 9 changed files with 823 additions and 444 deletions.
233 changes: 160 additions & 73 deletions drivers/audio/cs43l22.c

Large diffs are not rendered by default.

130 changes: 95 additions & 35 deletions drivers/audio/wm8776.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@
static void wm8776_writereg(FAR struct wm8776_dev_s *priv,
uint8_t regaddr, uint16_t regval);

static void wm8776_takesem(sem_t *sem);
static int wm8776_takesem(FAR sem_t *sem);
static int wm8776_forcetake(FAR sem_t *sem);
#define wm8776_givesem(s) nxsem_post(s)

static int wm8776_getcaps(FAR struct audio_lowerhalf_s *dev, int type,
Expand Down Expand Up @@ -174,13 +175,13 @@ static const struct audio_ops_s g_audioops =
wm8776_release /* release */
};

/************************************************************************************
/****************************************************************************
* Name: wm8776_writereg
*
* Description:
* Write the specified 16-bit register to the WM8776 device.
*
************************************************************************************/
****************************************************************************/

static void wm8776_writereg(FAR struct wm8776_dev_s *priv,
uint8_t regaddr,
Expand Down Expand Up @@ -208,28 +209,65 @@ static void wm8776_writereg(FAR struct wm8776_dev_s *priv,
}
}

/************************************************************************************
/****************************************************************************
* Name: wm8776_takesem
*
* Description:
* Take a semaphore count, handling the nasty EINTR return if we are interrupted
* by a signal.
* Take a semaphore count, handling the nasty EINTR return if we are
* interrupted by a signal.
*
************************************************************************************/
****************************************************************************/

static void wm8776_takesem(sem_t *sem)
static int wm8776_takesem(sem_t *sem)
{
nxsem_wait_uninterruptible(sem);
return nxsem_wait_uninterruptible(sem);
}

/************************************************************************************
/****************************************************************************
* Name: wm8776_forcetake
*
* Description:
* This is just another wrapper but this one continues even if the thread
* is canceled. This must be done in certain conditions where were must
* continue in order to clean-up resources.
*
****************************************************************************/

static int wm8776_forcetake(FAR sem_t *sem)
{
int result;
int ret = OK;

do
{
result = nxsem_wait_uninterruptible(sem);

/* The only expected error would -ECANCELED meaning that the
* parent thread has been canceled. We have to continue and
* terminate the poll in this case.
*/

DEBUGASSERT(result == OK || result == -ECANCELED);
if (ret == OK && result < 0)
{
/* Remember the first failure */

ret = result;
}
}
while (result < 0);

return ret;
}

/****************************************************************************
* Name: wm8776_setvolume
*
* Description:
* Set the right and left volume values in the WM8776 device based on the current
* volume and balance settings.
* Set the right and left volume values in the WM8776 device based on the
* current volume and balance settings.
*
************************************************************************************/
****************************************************************************/

#ifndef CONFIG_AUDIO_EXCLUDE_VOLUME
static void wm8776_setvolume(FAR struct wm8776_dev_s *priv, uint16_t volume,
Expand Down Expand Up @@ -312,8 +350,9 @@ static int wm8776_getcaps(FAR struct audio_lowerhalf_s *dev, int type,

/* The types of audio units we implement */

caps->ac_controls.b[0] = AUDIO_TYPE_OUTPUT | AUDIO_TYPE_FEATURE |
AUDIO_TYPE_PROCESSING;
caps->ac_controls.b[0] =
AUDIO_TYPE_OUTPUT | AUDIO_TYPE_FEATURE |
AUDIO_TYPE_PROCESSING;

break;

Expand Down Expand Up @@ -413,13 +452,14 @@ static int wm8776_configure(FAR struct audio_lowerhalf_s *dev,
{
/* Scale the volume setting to the range {0x2f .. 0x79} */

wm8776_setvolume(priv, (0x4a * volume / 1000) + 0x2f, priv->mute);
wm8776_setvolume(priv, (0x4a * volume / 1000) + 0x2f,
priv->mute);
}
else
{
ret = -EDOM;
}
}
}
break;
#endif /* CONFIG_AUDIO_EXCLUDE_VOLUME */

Expand Down Expand Up @@ -537,6 +577,7 @@ static void wm8776_senddone(FAR struct i2s_dev_s *i2s,
priv->inflight--;

/* Save the result of the transfer */

/* REVISIT: This can be overwritten */

priv->result = result;
Expand Down Expand Up @@ -639,7 +680,7 @@ static int wm8776_sendbuffer(FAR struct wm8776_dev_s *priv)
irqstate_t flags;
uint32_t timeout;
int shift;
int ret = OK;
int ret;

/* Loop while there are audio buffers to be sent and we have few than
* CONFIG_WM8776_INFLIGHT then "in-flight"
Expand All @@ -653,7 +694,12 @@ static int wm8776_sendbuffer(FAR struct wm8776_dev_s *priv)
* only while accessing 'inflight'.
*/

wm8776_takesem(&priv->pendsem);
ret = wm8776_takesem(&priv->pendsem);
if (ret < 0)
{
return ret;
}

while (priv->inflight < CONFIG_WM8776_INFLIGHT &&
dq_peek(&priv->pendq) != NULL && !priv->paused)
{
Expand Down Expand Up @@ -713,6 +759,7 @@ static int wm8776_start(FAR struct audio_lowerhalf_s *dev)
audinfo("Entry\n");

/* Exit reduced power modes of operation */

/* REVISIT */

/* Create a message queue for the worker thread */
Expand Down Expand Up @@ -796,6 +843,7 @@ static int wm8776_stop(FAR struct audio_lowerhalf_s *dev)
priv->threadid = 0;

/* Enter into a reduced power usage mode */

/* REVISIT: */

return OK;
Expand Down Expand Up @@ -837,7 +885,8 @@ static int wm8776_pause(FAR struct audio_lowerhalf_s *dev)

#ifndef CONFIG_AUDIO_EXCLUDE_PAUSE_RESUME
#ifdef CONFIG_AUDIO_MULTI_SESSION
static int wm8776_resume(FAR struct audio_lowerhalf_s *dev, FAR void *session)
static int wm8776_resume(FAR struct audio_lowerhalf_s *dev,
FAR void *session)
#else
static int wm8776_resume(FAR struct audio_lowerhalf_s *dev)
#endif
Expand Down Expand Up @@ -878,14 +927,20 @@ static int wm8776_enqueuebuffer(FAR struct audio_lowerhalf_s *dev,

/* Add the new buffer to the tail of pending audio buffers */

wm8776_takesem(&priv->pendsem);
ret = wm8776_takesem(&priv->pendsem);
if (ret < 0)
{
return ret;
}

apb->flags |= AUDIO_APB_OUTPUT_ENQUEUED;
dq_addlast(&apb->dq_entry, &priv->pendq);
wm8776_givesem(&priv->pendsem);

/* Send a message to the worker thread indicating that a new buffer has been
* enqueued. If mq is NULL, then the playing has not yet started. In that
* case we are just "priming the pump" and we don't need to send any message.
/* Send a message to the worker thread indicating that a new buffer has
* been enqueued. If mq is NULL, then the playing has not yet started.
* In that case we are just "priming the pump" and we don't need to send
* any message.
*/

ret = OK;
Expand Down Expand Up @@ -996,7 +1051,12 @@ static int wm8776_reserve(FAR struct audio_lowerhalf_s *dev)

/* Borrow the APBQ semaphore for thread sync */

wm8776_takesem(&priv->pendsem);
ret = wm8776_takesem(&priv->pendsem);
if (ret < 0)
{
return ret;
}

if (priv->reserved)
{
ret = -EBUSY;
Expand Down Expand Up @@ -1037,7 +1097,8 @@ static int wm8776_release(FAR struct audio_lowerhalf_s *dev)
#endif
{
FAR struct wm8776_dev_s *priv = (FAR struct wm8776_dev_s *)dev;
void *value;
FAR void *value;
int ret;

/* Join any old worker thread we had created to prevent a memory leak */

Expand All @@ -1049,14 +1110,14 @@ static int wm8776_release(FAR struct audio_lowerhalf_s *dev)

/* Borrow the APBQ semaphore for thread sync */

wm8776_takesem(&priv->pendsem);
ret = wm8776_forcetake(&priv->pendsem);

/* Really we should free any queued buffers here */

priv->reserved = false;
wm8776_givesem(&priv->pendsem);

return OK;
return ret;
}

/****************************************************************************
Expand All @@ -1075,11 +1136,12 @@ static int wm8776_release(FAR struct audio_lowerhalf_s *dev)

static void wm8776_audio_output(FAR struct wm8776_dev_s *priv)
{
wm8776_writereg(priv, WM8776_MASTER_ATT, WM8776_UPDATE | 0x58); /* -33db */
wm8776_writereg(priv, WM8776_DAC_IF, 0x32); /* 32bit, I2S, standard pol */
wm8776_writereg(priv, WM8776_MASTER_ATT,
WM8776_UPDATE | 0x58); /* -33db */
wm8776_writereg(priv, WM8776_DAC_IF, 0x32); /* 32bit, I2S, standard pol */

#ifdef CONFIG_WM8776_SWAP_HPOUT
wm8776_writereg(priv, WM8776_DAC_CC, 0x62); /* Swap HPOUT L/R */
wm8776_writereg(priv, WM8776_DAC_CC, 0x62); /* Swap HPOUT L/R */
#endif

wm8776_writereg(priv, WM8776_MASTER_MODE, 0x00); /* slave mode, 128fs */
Expand Down Expand Up @@ -1120,7 +1182,6 @@ static void wm8776_hw_reset(FAR struct wm8776_dev_s *priv)
/* Configure the WM8776 hardware as an audio input device */

wm8776_audio_output(priv);

}

/****************************************************************************
Expand Down Expand Up @@ -1203,6 +1264,7 @@ static void *wm8776_workerthread(pthread_addr_t pvarg)

#ifndef CONFIG_AUDIO_EXCLUDE_STOP
case AUDIO_MSG_STOP:

/* Indicate that we are terminating */

audinfo("AUDIO_MSG_STOP: Terminating\n");
Expand Down Expand Up @@ -1238,7 +1300,6 @@ static void *wm8776_workerthread(pthread_addr_t pvarg)
{
goto repeat;
}

}

/* Reset the WM8776 hardware */
Expand All @@ -1247,7 +1308,7 @@ static void *wm8776_workerthread(pthread_addr_t pvarg)

/* Return any pending buffers in our pending queue */

wm8776_takesem(&priv->pendsem);
wm8776_forcetake(&priv->pendsem);
while ((apb = (FAR struct ap_buffer_s *)dq_remfirst(&priv->pendq)) != NULL)
{
/* Release our reference to the buffer */
Expand Down Expand Up @@ -1287,7 +1348,6 @@ static void *wm8776_workerthread(pthread_addr_t pvarg)
return NULL;
}


/****************************************************************************
* Public Functions
****************************************************************************/
Expand Down
Loading

0 comments on commit 5b74974

Please sign in to comment.