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 rwbuffer.c and those files under drivers/serial, drivers/timers, and drivers/usbdev. This commit completes that step for all of the files under drivers/. Still remaining: All of the files under arch/.
This commit is contained in:
parent
a7415058e5
commit
9ff1795760
@ -1260,7 +1260,7 @@ static ssize_t tun_read(FAR struct file *filep, FAR char *buffer,
|
||||
size_t buflen)
|
||||
{
|
||||
FAR struct tun_device_s *priv = filep->f_priv;
|
||||
ssize_t nread;
|
||||
ssize_t nread = 0;
|
||||
int ret;
|
||||
|
||||
if (priv == NULL)
|
||||
|
@ -63,9 +63,37 @@
|
||||
* Name: rwb_semtake
|
||||
****************************************************************************/
|
||||
|
||||
static void rwb_semtake(FAR sem_t *sem)
|
||||
static int rwb_semtake(FAR sem_t *sem)
|
||||
{
|
||||
nxsem_wait_uninterruptible(sem);
|
||||
return nxsem_wait_uninterruptible(sem);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: rwb_forcetake
|
||||
****************************************************************************/
|
||||
|
||||
static int rwb_forcetake(FAR sem_t *sem)
|
||||
{
|
||||
int result;
|
||||
int ret = OK;
|
||||
|
||||
do
|
||||
{
|
||||
result = rwb_semtake(sem);
|
||||
|
||||
/* The only expected failure is if the thread is canceled */
|
||||
|
||||
DEBUGASSERT(result == OK || result == -ECANCELED);
|
||||
if (ret == OK && result < 0)
|
||||
{
|
||||
/* Remember the first error */
|
||||
|
||||
ret = result;
|
||||
}
|
||||
}
|
||||
while (result < 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -166,7 +194,7 @@ static void rwb_wrtimeout(FAR void *arg)
|
||||
* worker thread.
|
||||
*/
|
||||
|
||||
rwb_semtake(&rwb->wrsem);
|
||||
rwb_forcetake(&rwb->wrsem);
|
||||
rwb_wrflush(rwb);
|
||||
rwb_semgive(&rwb->wrsem);
|
||||
}
|
||||
@ -394,7 +422,11 @@ int rwb_invalidate_writebuffer(FAR struct rwbuffer_s *rwb,
|
||||
|
||||
finfo("startblock=%d blockcount=%p\n", startblock, blockcount);
|
||||
|
||||
rwb_semtake(&rwb->wrsem);
|
||||
ret = rwb_semtake(&rwb->wrsem);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Now there are five cases:
|
||||
*
|
||||
@ -531,7 +563,11 @@ int rwb_invalidate_readahead(FAR struct rwbuffer_s *rwb,
|
||||
|
||||
finfo("startblock=%d blockcount=%p\n", startblock, blockcount);
|
||||
|
||||
rwb_semtake(&rwb->rhsem);
|
||||
ret = rwb_semtake(&rwb->rhsem);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Now there are five cases:
|
||||
*
|
||||
@ -763,9 +799,14 @@ static ssize_t rwb_read_(FAR struct rwbuffer_s *rwb, off_t startblock,
|
||||
{
|
||||
size_t remaining;
|
||||
|
||||
ret = nxsem_wait(&rwb->rhsem);
|
||||
if (ret < 0)
|
||||
{
|
||||
return (ssize_t)ret;
|
||||
}
|
||||
|
||||
/* Loop until we have read all of the requested blocks */
|
||||
|
||||
rwb_semtake(&rwb->rhsem);
|
||||
for (remaining = nblocks; remaining > 0; )
|
||||
{
|
||||
/* Is there anything in the read-ahead buffer? */
|
||||
@ -852,9 +893,14 @@ ssize_t rwb_read(FAR struct rwbuffer_s *rwb, off_t startblock,
|
||||
|
||||
if (rwb->wrmaxblocks > 0)
|
||||
{
|
||||
ret = nxsem_wait(&rwb->wrsem);
|
||||
if (ret < 0)
|
||||
{
|
||||
return (ssize_t)ret;
|
||||
}
|
||||
|
||||
/* If the write buffer overlaps the block(s) requested */
|
||||
|
||||
rwb_semtake(&rwb->wrsem);
|
||||
if (rwb_overlap(rwb->wrblockstart, rwb->wrnblocks, startblock,
|
||||
nblocks))
|
||||
{
|
||||
@ -924,7 +970,12 @@ ssize_t rwb_write(FAR struct rwbuffer_s *rwb, off_t startblock,
|
||||
* streaming applications.
|
||||
*/
|
||||
|
||||
rwb_semtake(&rwb->rhsem);
|
||||
ret = nxsem_wait(&rwb->rhsem);
|
||||
if (ret < 0)
|
||||
{
|
||||
return (ssize_t)ret;
|
||||
}
|
||||
|
||||
if (rwb_overlap(rwb->rhblockstart, rwb->rhnblocks, startblock,
|
||||
nblocks))
|
||||
{
|
||||
@ -958,7 +1009,12 @@ ssize_t rwb_write(FAR struct rwbuffer_s *rwb, off_t startblock,
|
||||
{
|
||||
/* First flush the cache */
|
||||
|
||||
rwb_semtake(&rwb->wrsem);
|
||||
ret = nxsem_wait(&rwb->wrsem);
|
||||
if (ret < 0)
|
||||
{
|
||||
return (ssize_t)ret;
|
||||
}
|
||||
|
||||
rwb_wrflush(rwb);
|
||||
rwb_semgive(&rwb->wrsem);
|
||||
|
||||
@ -970,7 +1026,12 @@ ssize_t rwb_write(FAR struct rwbuffer_s *rwb, off_t startblock,
|
||||
{
|
||||
/* Buffer the data in the write buffer */
|
||||
|
||||
rwb_semtake(&rwb->wrsem);
|
||||
ret = nxsem_wait(&rwb->wrsem);
|
||||
if (ret < 0)
|
||||
{
|
||||
return (ssize_t)ret;
|
||||
}
|
||||
|
||||
ret = rwb_writebuffer(rwb, startblock, nblocks, wrbuffer);
|
||||
rwb_semgive(&rwb->wrsem);
|
||||
}
|
||||
@ -1036,7 +1097,12 @@ int rwb_mediaremoved(FAR struct rwbuffer_s *rwb)
|
||||
#ifdef CONFIG_DRVR_WRITEBUFFER
|
||||
if (rwb->wrmaxblocks > 0)
|
||||
{
|
||||
rwb_semtake(&rwb->wrsem);
|
||||
ret = rwb_semtake(&rwb->wrsem);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
rwb_resetwrbuffer(rwb);
|
||||
rwb_semgive(&rwb->wrsem);
|
||||
}
|
||||
@ -1045,7 +1111,12 @@ int rwb_mediaremoved(FAR struct rwbuffer_s *rwb)
|
||||
#ifdef CONFIG_DRVR_READAHEAD
|
||||
if (rwb->rhmaxblocks > 0)
|
||||
{
|
||||
rwb_semtake(&rwb->rhsem);
|
||||
ret = rwb_semtake(&rwb->rhsem);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
rwb_resetrhbuffer(rwb);
|
||||
rwb_semgive(&rwb->rhsem);
|
||||
}
|
||||
@ -1102,12 +1173,14 @@ int rwb_invalidate(FAR struct rwbuffer_s *rwb,
|
||||
#ifdef CONFIG_DRVR_WRITEBUFFER
|
||||
int rwb_flush(FAR struct rwbuffer_s *rwb)
|
||||
{
|
||||
rwb_semtake(&rwb->wrsem);
|
||||
int ret;
|
||||
|
||||
ret = rwb_forcetake(&rwb->wrsem);
|
||||
rwb_wrcanceltimeout(rwb);
|
||||
rwb_wrflush(rwb);
|
||||
rwb_semgive(&rwb->wrsem);
|
||||
|
||||
return OK;
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1,35 +1,20 @@
|
||||
/****************************************************************************
|
||||
* drivers/serial/ptmx.c
|
||||
*
|
||||
* Copyright (C) 2016-2018 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
@ -116,22 +101,6 @@ static struct ptmx_dev_s g_ptmx;
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ptmx_semtake and ptmx_semgive
|
||||
*
|
||||
* Description:
|
||||
* This is just a wrapper to handle the annoying behavior of semaphore
|
||||
* waits that return due to the receipt of a signal.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void ptmx_semtake(void)
|
||||
{
|
||||
nxsem_wait_uninterruptible(&g_ptmx.px_exclsem);
|
||||
}
|
||||
|
||||
#define ptmx_semgive() nxsem_post(&g_ptmx.px_exclsem)
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ptmx_minor_allocate
|
||||
*
|
||||
@ -204,7 +173,11 @@ static int ptmx_open(FAR struct file *filep)
|
||||
|
||||
/* Get exclusive access */
|
||||
|
||||
ptmx_semtake();
|
||||
ret = nxsem_wait(&g_ptmx.px_exclsem);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Allocate a PTY minor */
|
||||
|
||||
@ -246,7 +219,7 @@ static int ptmx_open(FAR struct file *filep)
|
||||
|
||||
/* Return the encoded, master file descriptor */
|
||||
|
||||
ptmx_semgive();
|
||||
nxsem_post(&g_ptmx.px_exclsem);
|
||||
DEBUGASSERT((unsigned)fd <= OPEN_MAXFD);
|
||||
return (int)OPEN_SETFD(fd);
|
||||
|
||||
@ -254,7 +227,7 @@ errout_with_minor:
|
||||
ptmx_minor_free(minor);
|
||||
|
||||
errout_with_sem:
|
||||
ptmx_semgive();
|
||||
nxsem_post(&g_ptmx.px_exclsem);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -262,7 +235,8 @@ errout_with_sem:
|
||||
* Name: ptmx_read
|
||||
****************************************************************************/
|
||||
|
||||
static ssize_t ptmx_read(FAR struct file *filep, FAR char *buffer, size_t len)
|
||||
static ssize_t ptmx_read(FAR struct file *filep,
|
||||
FAR char *buffer, size_t len)
|
||||
{
|
||||
return 0; /* Return EOF */
|
||||
}
|
||||
@ -271,7 +245,8 @@ static ssize_t ptmx_read(FAR struct file *filep, FAR char *buffer, size_t len)
|
||||
* Name: ptmx_write
|
||||
****************************************************************************/
|
||||
|
||||
static ssize_t ptmx_write(FAR struct file *filep, FAR const char *buffer, size_t len)
|
||||
static ssize_t ptmx_write(FAR struct file *filep,
|
||||
FAR const char *buffer, size_t len)
|
||||
{
|
||||
return len; /* Say that everything was written */
|
||||
}
|
||||
|
@ -1,35 +1,20 @@
|
||||
/****************************************************************************
|
||||
* drivers/serial/pty.c
|
||||
*
|
||||
* Copyright (C) 2016-2018 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
@ -168,7 +153,7 @@ struct pty_devpair_s
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
static void pty_semtake(FAR struct pty_devpair_s *devpair);
|
||||
static int pty_semtake(FAR struct pty_devpair_s *devpair);
|
||||
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
|
||||
static void pty_destroy(FAR struct pty_devpair_s *devpair);
|
||||
#endif
|
||||
@ -219,9 +204,9 @@ static const struct file_operations g_pty_fops =
|
||||
* Name: pty_semtake
|
||||
****************************************************************************/
|
||||
|
||||
static void pty_semtake(FAR struct pty_devpair_s *devpair)
|
||||
static int pty_semtake(FAR struct pty_devpair_s *devpair)
|
||||
{
|
||||
nxsem_wait_uninterruptible(&devpair->pp_exclsem);
|
||||
return nxsem_wait_uninterruptible(&devpair->pp_exclsem);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -309,36 +294,48 @@ static int pty_open(FAR struct file *filep)
|
||||
{
|
||||
/* Wait until unlocked. We will also most certainly suspend here. */
|
||||
|
||||
nxsem_wait(&devpair->pp_slavesem);
|
||||
ret = nxsem_wait(&devpair->pp_slavesem);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Get exclusive access to the device structure. This might also
|
||||
* cause suspension.
|
||||
*/
|
||||
|
||||
pty_semtake(devpair);
|
||||
ret = pty_semtake(devpair);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Check again in case something happened asynchronously while we
|
||||
* were suspended.
|
||||
*/
|
||||
|
||||
if (devpair->pp_locked)
|
||||
{
|
||||
/* This cannot suspend because we have the scheduler locked.
|
||||
* So pp_locked cannot change asyncrhonously between this test
|
||||
* and the redundant test at the top of the loop.
|
||||
*/
|
||||
{
|
||||
/* This cannot suspend because we have the scheduler locked.
|
||||
* So pp_locked cannot change asyncrhonously between this test
|
||||
* and the redundant test at the top of the loop.
|
||||
*/
|
||||
|
||||
pty_semgive(devpair);
|
||||
}
|
||||
pty_semgive(devpair);
|
||||
}
|
||||
}
|
||||
|
||||
sched_unlock();
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Master ... Get exclusive access to the device structure */
|
||||
/* Master ... Get exclusive access to the device structure */
|
||||
|
||||
pty_semtake(devpair);
|
||||
ret = pty_semtake(devpair);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto errout_with_sem;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef CONFIG_PSEUDOTERM_SUSV1
|
||||
@ -364,6 +361,7 @@ static int pty_open(FAR struct file *filep)
|
||||
ret = OK;
|
||||
}
|
||||
|
||||
errout_with_sem:
|
||||
pty_semgive(devpair);
|
||||
return ret;
|
||||
}
|
||||
@ -379,6 +377,7 @@ static int pty_close(FAR struct file *filep)
|
||||
FAR struct inode *inode;
|
||||
FAR struct pty_dev_s *dev;
|
||||
FAR struct pty_devpair_s *devpair;
|
||||
int ret;
|
||||
|
||||
DEBUGASSERT(filep != NULL && filep->f_inode != NULL);
|
||||
inode = filep->f_inode;
|
||||
@ -388,7 +387,11 @@ static int pty_close(FAR struct file *filep)
|
||||
|
||||
/* Get exclusive access */
|
||||
|
||||
pty_semtake(devpair);
|
||||
ret = pty_semtake(devpair);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PSEUDOTERM_SUSV1
|
||||
/* Did the (single) master just close its reference? */
|
||||
@ -561,6 +564,7 @@ static ssize_t pty_read(FAR struct file *filep, FAR char *buffer, size_t len)
|
||||
}
|
||||
|
||||
/* Perform input processing */
|
||||
|
||||
/* \n -> \r or \r -> \n translation? */
|
||||
|
||||
if (ch == '\n' && (dev->pd_iflag & INLCR) != 0)
|
||||
@ -578,7 +582,6 @@ static ssize_t pty_read(FAR struct file *filep, FAR char *buffer, size_t len)
|
||||
|
||||
if (ch != '\r' || (dev->pd_iflag & IGNCR) == 0)
|
||||
{
|
||||
|
||||
/* Transfer the (possibly translated) character and update the
|
||||
* count of bytes transferred.
|
||||
*/
|
||||
@ -612,7 +615,8 @@ static ssize_t pty_read(FAR struct file *filep, FAR char *buffer, size_t len)
|
||||
* Name: pty_write
|
||||
****************************************************************************/
|
||||
|
||||
static ssize_t pty_write(FAR struct file *filep, FAR const char *buffer, size_t len)
|
||||
static ssize_t pty_write(FAR struct file *filep,
|
||||
FAR const char *buffer, size_t len)
|
||||
{
|
||||
FAR struct inode *inode;
|
||||
FAR struct pty_dev_s *dev;
|
||||
@ -743,7 +747,11 @@ static int pty_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
|
||||
|
||||
/* Get exclusive access */
|
||||
|
||||
pty_semtake(devpair);
|
||||
ret = pty_semtake(devpair);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Handle IOCTL commands */
|
||||
|
||||
@ -920,7 +928,7 @@ static int pty_poll(FAR struct file *filep, FAR struct pollfd *fds,
|
||||
FAR struct pty_dev_s *dev;
|
||||
FAR struct pty_devpair_s *devpair;
|
||||
FAR struct pty_poll_s *pollp = NULL;
|
||||
int ret = -ENOSYS;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
DEBUGASSERT(filep != NULL && filep->f_inode != NULL);
|
||||
@ -928,7 +936,13 @@ static int pty_poll(FAR struct file *filep, FAR struct pollfd *fds,
|
||||
dev = inode->i_private;
|
||||
devpair = dev->pd_devpair;
|
||||
|
||||
pty_semtake(devpair);
|
||||
ret = pty_semtake(devpair);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = -ENOSYS;
|
||||
|
||||
if (setup)
|
||||
{
|
||||
@ -983,6 +997,7 @@ static int pty_poll(FAR struct file *filep, FAR struct pollfd *fds,
|
||||
|
||||
goto errout;
|
||||
}
|
||||
|
||||
pollp->sink = fds->priv;
|
||||
}
|
||||
|
||||
@ -1005,6 +1020,7 @@ static int pty_unlink(FAR struct inode *inode)
|
||||
{
|
||||
FAR struct pty_dev_s *dev;
|
||||
FAR struct pty_devpair_s *devpair;
|
||||
int ret;
|
||||
|
||||
DEBUGASSERT(inode != NULL && inode->i_private != NULL);
|
||||
dev = inode->i_private;
|
||||
@ -1013,7 +1029,11 @@ static int pty_unlink(FAR struct inode *inode)
|
||||
|
||||
/* Get exclusive access */
|
||||
|
||||
pty_semtake(devpair);
|
||||
ret = pty_semtake(devpair);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Indicate that the driver has been unlinked */
|
||||
|
||||
@ -1033,6 +1053,7 @@ static int pty_unlink(FAR struct inode *inode)
|
||||
return OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
@ -1230,8 +1251,8 @@ errout_with_pipea:
|
||||
}
|
||||
|
||||
errout_with_devpair:
|
||||
nxsem_destroy(&devpair->pp_exclsem);
|
||||
nxsem_destroy(&devpair->pp_slavesem);
|
||||
kmm_free(devpair);
|
||||
return ret;
|
||||
nxsem_destroy(&devpair->pp_exclsem);
|
||||
nxsem_destroy(&devpair->pp_slavesem);
|
||||
kmm_free(devpair);
|
||||
return ret;
|
||||
}
|
||||
|
@ -1,35 +1,20 @@
|
||||
/****************************************************************************
|
||||
* drivers/timers/pwm.c
|
||||
*
|
||||
* Copyright (C) 2011-2013, 2016-2017 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
@ -68,16 +53,20 @@
|
||||
|
||||
struct pwm_upperhalf_s
|
||||
{
|
||||
uint8_t crefs; /* The number of times the device has been opened */
|
||||
volatile bool started; /* True: pulsed output is being generated */
|
||||
uint8_t crefs; /* The number of times the device has
|
||||
* been opened */
|
||||
volatile bool started; /* True: pulsed output is being
|
||||
* generated */
|
||||
#ifdef CONFIG_PWM_PULSECOUNT
|
||||
volatile bool waiting; /* True: Caller is waiting for the pulse count to expire */
|
||||
volatile bool waiting; /* True: Caller is waiting for the pulse
|
||||
* count to expire */
|
||||
#endif
|
||||
sem_t exclsem; /* Supports mutual exclusion */
|
||||
sem_t exclsem; /* Supports mutual exclusion */
|
||||
#ifdef CONFIG_PWM_PULSECOUNT
|
||||
sem_t waitsem; /* Used to wait for the pulse count to expire */
|
||||
sem_t waitsem; /* Used to wait for the pulse count to
|
||||
* expire */
|
||||
#endif
|
||||
struct pwm_info_s info; /* Pulsed output characteristics */
|
||||
struct pwm_info_s info; /* Pulsed output characteristics */
|
||||
FAR struct pwm_lowerhalf_s *dev; /* lower-half state */
|
||||
};
|
||||
|
||||
@ -336,7 +325,8 @@ static int pwm_start(FAR struct pwm_upperhalf_s *upper, unsigned int oflags)
|
||||
* We do these things before starting the PWM to avoid race conditions.
|
||||
*/
|
||||
|
||||
upper->waiting = (upper->info.count > 0) && ((oflags & O_NONBLOCK) == 0);
|
||||
upper->waiting = (upper->info.count > 0) &&
|
||||
((oflags & O_NONBLOCK) == 0);
|
||||
upper->started = true;
|
||||
|
||||
/* Invoke the bottom half method to start the pulse train */
|
||||
@ -360,7 +350,12 @@ static int pwm_start(FAR struct pwm_upperhalf_s *upper, unsigned int oflags)
|
||||
* clear the waiting flag.
|
||||
*/
|
||||
|
||||
nxsem_wait_uninterruptible(&upper->waitsem);
|
||||
ret = nxsem_wait_uninterruptible(&upper->waitsem);
|
||||
if (ret < 0)
|
||||
{
|
||||
upper->started = false;
|
||||
upper->waiting = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -440,14 +435,15 @@ static int pwm_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
/* PWMIOC_SETCHARACTERISTICS - Set the characteristics of the next pulsed
|
||||
* output. This command will neither start nor stop the pulsed output.
|
||||
* It will either setup the configuration that will be used when the
|
||||
* output is started; or it will change the characteristics of the pulsed
|
||||
* output on the fly if the timer is already started.
|
||||
/* PWMIOC_SETCHARACTERISTICS - Set the characteristics of the next
|
||||
* pulsed output. This command will neither start nor stop the
|
||||
* pulsed output. It will either setup the configuration that will
|
||||
* be used when the output is started; or it will change the
|
||||
* characteristics of the pulsed output on the fly if the timer is
|
||||
* already started.
|
||||
*
|
||||
* ioctl argument: A read-only reference to struct pwm_info_s that provides
|
||||
* the characteristics of the pulsed output.
|
||||
* ioctl argument: A read-only reference to struct pwm_info_s that
|
||||
* provides the characteristics of the pulsed output.
|
||||
*/
|
||||
|
||||
case PWMIOC_SETCHARACTERISTICS:
|
||||
@ -475,8 +471,9 @@ static int pwm_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
|
||||
}
|
||||
break;
|
||||
|
||||
/* PWMIOC_GETCHARACTERISTICS - Get the currently selected characteristics of
|
||||
* the pulsed output (independent of whether the output is start or stopped).
|
||||
/* PWMIOC_GETCHARACTERISTICS - Get the currently selected
|
||||
* characteristics of the pulsed output (independent of whether the
|
||||
* output is start or stopped).
|
||||
*
|
||||
* ioctl argument: A reference to struct pwm_info_s to receive the
|
||||
* characteristics of the pulsed output.
|
||||
@ -484,7 +481,8 @@ static int pwm_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
|
||||
|
||||
case PWMIOC_GETCHARACTERISTICS:
|
||||
{
|
||||
FAR struct pwm_info_s *info = (FAR struct pwm_info_s *)((uintptr_t)arg);
|
||||
FAR struct pwm_info_s *info =
|
||||
(FAR struct pwm_info_s *)((uintptr_t)arg);
|
||||
DEBUGASSERT(info != NULL);
|
||||
|
||||
memcpy(info, &upper->info, sizeof(struct pwm_info_s));
|
||||
@ -493,8 +491,8 @@ static int pwm_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
|
||||
}
|
||||
break;
|
||||
|
||||
/* PWMIOC_START - Start the pulsed output. The PWMIOC_SETCHARACTERISTICS
|
||||
* command must have previously been sent.
|
||||
/* PWMIOC_START - Start the pulsed output. The
|
||||
* PWMIOC_SETCHARACTERISTICS command must have previously been sent.
|
||||
*
|
||||
* ioctl argument: None
|
||||
*/
|
||||
@ -569,9 +567,9 @@ static int pwm_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
|
||||
* filesystem. The recommended convention is to name all PWM drivers
|
||||
* as "/dev/pwm0", "/dev/pwm1", etc. where the driver path differs only
|
||||
* in the "minor" number at the end of the device name.
|
||||
* dev - A pointer to an instance of lower half timer driver. This instance
|
||||
* is bound to the PWM driver and must persists as long as the driver
|
||||
* persists.
|
||||
* dev - A pointer to an instance of lower half timer driver. This
|
||||
* instance is bound to the PWM driver and must persists as long as the
|
||||
* driver persists.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero on success; a negated errno value on failure.
|
||||
@ -584,7 +582,8 @@ int pwm_register(FAR const char *path, FAR struct pwm_lowerhalf_s *dev)
|
||||
|
||||
/* Allocate the upper-half data structure */
|
||||
|
||||
upper = (FAR struct pwm_upperhalf_s *)kmm_zalloc(sizeof(struct pwm_upperhalf_s));
|
||||
upper = (FAR struct pwm_upperhalf_s *)
|
||||
kmm_zalloc(sizeof(struct pwm_upperhalf_s));
|
||||
if (!upper)
|
||||
{
|
||||
pwmerr("Allocation failed\n");
|
||||
@ -597,8 +596,8 @@ int pwm_register(FAR const char *path, FAR struct pwm_lowerhalf_s *dev)
|
||||
#ifdef CONFIG_PWM_PULSECOUNT
|
||||
nxsem_init(&upper->waitsem, 0, 0);
|
||||
|
||||
/* The wait semaphore is used for signaling and, hence, should not have priority
|
||||
* inheritance enabled.
|
||||
/* The wait semaphore is used for signaling and, hence, should not have
|
||||
* priority inheritance enabled.
|
||||
*/
|
||||
|
||||
nxsem_setprotocol(&upper->waitsem, SEM_PRIO_NONE);
|
||||
|
@ -1,12 +1,25 @@
|
||||
/****************************************************************************
|
||||
* drivers/usbdev/usbmsc.c
|
||||
*
|
||||
* Copyright (C) 2008-2012, 2016-2017 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Mass storage class device. Bulk-only with SCSI subclass.
|
||||
*
|
||||
* References:
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/* References:
|
||||
* "Universal Serial Bus Mass Storage Class, Specification Overview,"
|
||||
* Revision 1.2, USB Implementer's Forum, June 23, 2003.
|
||||
*
|
||||
@ -24,35 +37,7 @@
|
||||
*
|
||||
* "SCSI Multimedia Commands - 3 (MMC-3)," American National Standard
|
||||
* for Information Technology, November 12, 2001
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
*/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
@ -173,9 +158,6 @@ FAR struct usbmsc_dev_s *g_usbmsc_handoff;
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Class Driver Support
|
||||
****************************************************************************/
|
||||
/****************************************************************************
|
||||
* Name: usbmsc_ep0incomplete
|
||||
*
|
||||
@ -230,7 +212,8 @@ static struct usbdev_req_s *usbmsc_allocreq(FAR struct usbdev_ep_s *ep,
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void usbmsc_freereq(FAR struct usbdev_ep_s *ep, struct usbdev_req_s *req)
|
||||
static void usbmsc_freereq(FAR struct usbdev_ep_s *ep,
|
||||
FAR struct usbdev_req_s *req)
|
||||
{
|
||||
if (ep != NULL && req != NULL)
|
||||
{
|
||||
@ -238,6 +221,7 @@ static void usbmsc_freereq(FAR struct usbdev_ep_s *ep, struct usbdev_req_s *req)
|
||||
{
|
||||
EP_FREEBUFFER(ep, req->buf);
|
||||
}
|
||||
|
||||
EP_FREEREQ(ep, req);
|
||||
}
|
||||
}
|
||||
@ -257,7 +241,8 @@ static void usbmsc_freereq(FAR struct usbdev_ep_s *ep, struct usbdev_req_s *req)
|
||||
static int usbmsc_bind(FAR struct usbdevclass_driver_s *driver,
|
||||
FAR struct usbdev_s *dev)
|
||||
{
|
||||
FAR struct usbmsc_dev_s *priv = ((FAR struct usbmsc_driver_s *)driver)->dev;
|
||||
FAR struct usbmsc_dev_s *priv =
|
||||
((FAR struct usbmsc_driver_s *)driver)->dev;
|
||||
FAR struct usbmsc_req_s *reqcontainer;
|
||||
irqstate_t flags;
|
||||
int ret = OK;
|
||||
@ -416,7 +401,7 @@ static void usbmsc_unbind(FAR struct usbdevclass_driver_s *driver,
|
||||
{
|
||||
usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_UNBINDINVALIDARGS), 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Extract reference to private data */
|
||||
@ -435,7 +420,8 @@ static void usbmsc_unbind(FAR struct usbdevclass_driver_s *driver,
|
||||
* driver un-initialize logic.
|
||||
*/
|
||||
|
||||
DEBUGASSERT(priv->thstate == USBMSC_STATE_TERMINATED || priv->thstate == USBMSC_STATE_NOTSTARTED);
|
||||
DEBUGASSERT(priv->thstate == USBMSC_STATE_TERMINATED ||
|
||||
priv->thstate == USBMSC_STATE_NOTSTARTED);
|
||||
|
||||
/* Make sure that we are not already unbound */
|
||||
|
||||
@ -550,6 +536,7 @@ static int usbmsc_setup(FAR struct usbdevclass_driver_s *driver,
|
||||
return -ENODEV;
|
||||
}
|
||||
#endif
|
||||
|
||||
ctrlreq = priv->ctrlreq;
|
||||
|
||||
/* Extract the little-endian 16-bit values to host order */
|
||||
@ -571,8 +558,9 @@ static int usbmsc_setup(FAR struct usbdevclass_driver_s *driver,
|
||||
{
|
||||
case USB_REQ_GETDESCRIPTOR:
|
||||
{
|
||||
/* The value field specifies the descriptor type in the MS byte and the
|
||||
* descriptor index in the LS byte (order is little endian)
|
||||
/* The value field specifies the descriptor type in the MS byte
|
||||
* and the descriptor index in the LS byte (order is little
|
||||
* endian)
|
||||
*/
|
||||
|
||||
switch (ctrl->value[1])
|
||||
@ -607,9 +595,9 @@ static int usbmsc_setup(FAR struct usbdevclass_driver_s *driver,
|
||||
case USB_DESC_TYPE_OTHERSPEEDCONFIG:
|
||||
#endif
|
||||
|
||||
/* If the mass storage device is used in as part of a composite device,
|
||||
* then the configuration descriptor is provided by logic in the
|
||||
* composite device implementation.
|
||||
/* If the mass storage device is used in as part of a
|
||||
* composite device, then the configuration descriptor is
|
||||
* provided by logic in the composite device implementation.
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_USBMSC_COMPOSITE
|
||||
@ -636,14 +624,16 @@ static int usbmsc_setup(FAR struct usbdevclass_driver_s *driver,
|
||||
/* index == language code. */
|
||||
|
||||
ret = usbmsc_mkstrdesc(ctrl->value[0],
|
||||
(struct usb_strdesc_s *)ctrlreq->buf);
|
||||
(FAR struct usb_strdesc_s *)
|
||||
ctrlreq->buf);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
{
|
||||
usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_GETUNKNOWNDESC), value);
|
||||
usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_GETUNKNOWNDESC),
|
||||
value);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -730,7 +720,8 @@ static int usbmsc_setup(FAR struct usbdevclass_driver_s *driver,
|
||||
break;
|
||||
|
||||
default:
|
||||
usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_UNSUPPORTEDSTDREQ), ctrl->req);
|
||||
usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_UNSUPPORTEDSTDREQ),
|
||||
ctrl->req);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -758,7 +749,8 @@ static int usbmsc_setup(FAR struct usbdevclass_driver_s *driver,
|
||||
|
||||
if (index != USBMSC_INTERFACEID)
|
||||
{
|
||||
usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_MSRESETNDX), index);
|
||||
usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_MSRESETNDX),
|
||||
index);
|
||||
ret = -EDOM;
|
||||
}
|
||||
else
|
||||
@ -788,7 +780,8 @@ static int usbmsc_setup(FAR struct usbdevclass_driver_s *driver,
|
||||
|
||||
if (index != USBMSC_INTERFACEID)
|
||||
{
|
||||
usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_GETMAXLUNNDX), index);
|
||||
usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_GETMAXLUNNDX),
|
||||
index);
|
||||
ret = -EDOM;
|
||||
}
|
||||
else
|
||||
@ -867,7 +860,7 @@ static void usbmsc_disconnect(FAR struct usbdevclass_driver_s *driver,
|
||||
{
|
||||
usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_DISCONNECTINVALIDARGS), 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Extract reference to private data */
|
||||
@ -1289,9 +1282,9 @@ void usbmsc_deferredresponse(FAR struct usbmsc_dev_s *priv, bool failed)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void usbmsc_sync_wait(FAR struct usbmsc_dev_s *priv)
|
||||
static int usbmsc_sync_wait(FAR struct usbmsc_dev_s *priv)
|
||||
{
|
||||
nxsem_wait_uninterruptible(&priv->thsynch);
|
||||
return nxsem_wait_uninterruptible(&priv->thsynch);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -1336,7 +1329,8 @@ int usbmsc_configure(unsigned int nluns, void **handle)
|
||||
|
||||
/* Allocate the structures needed */
|
||||
|
||||
alloc = (FAR struct usbmsc_alloc_s *)kmm_malloc(sizeof(struct usbmsc_alloc_s));
|
||||
alloc = (FAR struct usbmsc_alloc_s *)
|
||||
kmm_malloc(sizeof(struct usbmsc_alloc_s));
|
||||
if (!alloc)
|
||||
{
|
||||
usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_ALLOCDEVSTRUCT), 0);
|
||||
@ -1390,15 +1384,17 @@ int usbmsc_configure(unsigned int nluns, void **handle)
|
||||
|
||||
/* Initialize the device information if we are not part of a composite.
|
||||
* If we are part of a composite, the device information will be
|
||||
* initialized through coordinated actions of usbmsc_get_composite_devdesc()
|
||||
* and board-specific logic.
|
||||
* initialized through coordinated actions of
|
||||
* usbmsc_get_composite_devdesc() and board-specific logic.
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_USBMSC_COMPOSITE
|
||||
/* minor - not used */
|
||||
|
||||
/* Interfaces (ifnobase == 0) */
|
||||
|
||||
priv->devinfo.ninterfaces = USBMSC_NINTERFACES; /* Number of interfaces in the configuration */
|
||||
priv->devinfo.ninterfaces = USBMSC_NINTERFACES; /* Number of interfaces
|
||||
* in the configuration */
|
||||
|
||||
/* Strings (strbase == 0) */
|
||||
|
||||
@ -1428,7 +1424,8 @@ errout:
|
||||
* Bind the block driver specified by drvrpath to a USB storage LUN.
|
||||
*
|
||||
* Input Parameters:
|
||||
* handle - The handle returned by a previous call to usbmsc_configure().
|
||||
* handle - The handle returned by a previous call to
|
||||
* usbmsc_configure().
|
||||
* drvrpath - the full path to the block driver
|
||||
* startsector - A sector offset into the block driver to the start of the
|
||||
* partition on drvrpath (0 if no partitions)
|
||||
@ -1536,7 +1533,8 @@ int usbmsc_bindlun(FAR void *handle, FAR const char *drvrpath,
|
||||
priv->iobuffer = (FAR uint8_t *)kmm_malloc(geo.geo_sectorsize);
|
||||
if (!priv->iobuffer)
|
||||
{
|
||||
usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_ALLOCIOBUFFER), geo.geo_sectorsize);
|
||||
usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_ALLOCIOBUFFER),
|
||||
geo.geo_sectorsize);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
@ -1549,7 +1547,8 @@ int usbmsc_bindlun(FAR void *handle, FAR const char *drvrpath,
|
||||
tmp = (FAR void *)kmm_realloc(priv->iobuffer, geo.geo_sectorsize);
|
||||
if (!tmp)
|
||||
{
|
||||
usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_REALLOCIOBUFFER), geo.geo_sectorsize);
|
||||
usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_REALLOCIOBUFFER),
|
||||
geo.geo_sectorsize);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
@ -1620,7 +1619,11 @@ int usbmsc_unbindlun(FAR void *handle, unsigned int lunno)
|
||||
#endif
|
||||
|
||||
lun = &priv->luntab[lunno];
|
||||
usbmsc_scsi_lock(priv);
|
||||
ret = usbmsc_scsi_lock(priv);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DEBUG_FEATURES
|
||||
if (lun->inode == NULL)
|
||||
@ -1630,12 +1633,12 @@ int usbmsc_unbindlun(FAR void *handle, unsigned int lunno)
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
{
|
||||
/* Close the block driver */
|
||||
|
||||
usbmsc_lununinitialize(lun);
|
||||
ret = OK;
|
||||
}
|
||||
usbmsc_lununinitialize(lun);
|
||||
ret = OK;
|
||||
}
|
||||
|
||||
usbmsc_scsi_unlock(priv);
|
||||
return ret;
|
||||
@ -1667,7 +1670,7 @@ int usbmsc_exportluns(FAR void *handle)
|
||||
FAR struct usbmsc_driver_s *drvr;
|
||||
#endif
|
||||
irqstate_t flags;
|
||||
int ret = OK;
|
||||
int ret;
|
||||
|
||||
#ifdef CONFIG_DEBUG_FEATURES
|
||||
if (!alloc)
|
||||
@ -1688,7 +1691,11 @@ int usbmsc_exportluns(FAR void *handle)
|
||||
* some protection against re-entrant usage.
|
||||
*/
|
||||
|
||||
usbmsc_scsi_lock(priv);
|
||||
ret = usbmsc_scsi_lock(priv);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
priv->thstate = USBMSC_STATE_NOTSTARTED;
|
||||
priv->theventset = USBMSC_EVENT_NOEVENTS;
|
||||
@ -1709,7 +1716,12 @@ int usbmsc_exportluns(FAR void *handle)
|
||||
/* Wait for the worker thread to run and initialize */
|
||||
|
||||
uinfo("Waiting for the SCSI worker thread\n");
|
||||
usbmsc_sync_wait(priv);
|
||||
ret = usbmsc_sync_wait(priv);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto errout_with_lock;
|
||||
}
|
||||
|
||||
DEBUGASSERT(g_usbmsc_handoff == NULL);
|
||||
|
||||
/* Register the USB storage class driver (unless we are part of a composite device) */
|
||||
@ -1800,6 +1812,7 @@ void usbmsc_uninitialize(FAR void *handle)
|
||||
FAR struct usbmsc_alloc_s *alloc = (FAR struct usbmsc_alloc_s *)handle;
|
||||
FAR struct usbmsc_dev_s *priv;
|
||||
irqstate_t flags;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
#ifdef CONFIG_DEBUG_FEATURES
|
||||
@ -1832,9 +1845,23 @@ void usbmsc_uninitialize(FAR void *handle)
|
||||
|
||||
if (priv->thstate != USBMSC_STATE_NOTSTARTED)
|
||||
{
|
||||
/* The thread was started.. Is it still running? */
|
||||
/* Get exclusive access to SCSI state data */
|
||||
|
||||
do
|
||||
{
|
||||
ret = usbmsc_scsi_lock(priv);
|
||||
|
||||
/* usbmsc_scsi_lock() will fail with ECANCELED, only
|
||||
* if this thread is canceled. At this point, we
|
||||
* have no option but to continue with the teardown.
|
||||
*/
|
||||
|
||||
DEBUGASSERT(ret == OK || ret == -ECANCLED);
|
||||
}
|
||||
while (ret < 0);
|
||||
|
||||
/* The thread was started.. Is it still running? */
|
||||
|
||||
usbmsc_scsi_lock(priv);
|
||||
if (priv->thstate != USBMSC_STATE_TERMINATED)
|
||||
{
|
||||
/* Yes.. Ask the thread to stop */
|
||||
@ -1851,7 +1878,15 @@ void usbmsc_uninitialize(FAR void *handle)
|
||||
|
||||
while ((priv->theventset & USBMSC_EVENT_TERMINATEREQUEST) != 0)
|
||||
{
|
||||
usbmsc_sync_wait(priv);
|
||||
ret = usbmsc_sync_wait(priv);
|
||||
if (ret < 0)
|
||||
{
|
||||
/* Just break out and continue if the thread has been
|
||||
* canceled.
|
||||
*/
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,37 +1,21 @@
|
||||
/****************************************************************************
|
||||
* drivers/usbdev/usbmsc.h
|
||||
*
|
||||
* Copyright (C) 2008-2013, 2015, 2017 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Mass storage class device. Bulk-only with SCSI subclass.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
@ -425,7 +409,7 @@ struct usbmsc_dev_s
|
||||
|
||||
struct usbmsc_lun_s *lun; /* Currently selected LUN */
|
||||
struct usbmsc_lun_s *luntab; /* Allocated table of all LUNs */
|
||||
uint8_t cdb[USBMSC_MAXCDBLEN]; /* Command data (cdb[]) from CBW */
|
||||
uint8_t cdb[USBMSC_MAXCDBLEN]; /* Command data (cdb[]) from CBW */
|
||||
uint8_t phaseerror:1; /* Need to send phase sensing status */
|
||||
uint8_t shortpacket:1; /* Host transmission stopped unexpectedly */
|
||||
uint8_t cbwdir:2; /* Direction from CBW. See USBMSC_FLAGS_DIR* definitions */
|
||||
@ -483,8 +467,8 @@ EXTERN const char g_mscvendorstr[];
|
||||
EXTERN const char g_mscproductstr[];
|
||||
EXTERN const char g_mscserialstr[];
|
||||
|
||||
/* If we are using a composite device, then vendor/product/serial number strings
|
||||
* are provided by the composite device logic.
|
||||
/* If we are using a composite device, then vendor/product/serial number
|
||||
* strings are provided by the composite device logic.
|
||||
*/
|
||||
|
||||
#else
|
||||
@ -513,7 +497,7 @@ EXTERN FAR struct usbmsc_dev_s *g_usbmsc_handoff;
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void usbmsc_scsi_lock(FAR struct usbmsc_dev_s *priv);
|
||||
int usbmsc_scsi_lock(FAR struct usbmsc_dev_s *priv);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: usbmsc_scsi_unlock
|
||||
@ -525,7 +509,7 @@ void usbmsc_scsi_lock(FAR struct usbmsc_dev_s *priv);
|
||||
|
||||
#define usbmsc_scsi_unlock(priv) nxsem_post(&priv->thlock)
|
||||
|
||||
/*****************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: usbmsc_scsi_signal
|
||||
*
|
||||
* Description:
|
||||
@ -591,10 +575,12 @@ int usbmsc_copy_epdesc(enum usbmsc_epdesc_e epid,
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_USBDEV_DUALSPEED
|
||||
int16_t usbmsc_mkcfgdesc(FAR uint8_t *buf, FAR struct usbdev_devinfo_s *devinfo,
|
||||
int16_t usbmsc_mkcfgdesc(FAR uint8_t *buf,
|
||||
FAR struct usbdev_devinfo_s *devinfo,
|
||||
uint8_t speed, uint8_t type);
|
||||
#else
|
||||
int16_t usbmsc_mkcfgdesc(FAR uint8_t *buf, FAR struct usbdev_devinfo_s *devinfo);
|
||||
int16_t usbmsc_mkcfgdesc(FAR uint8_t *buf,
|
||||
FAR struct usbdev_devinfo_s *devinfo);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user