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:
Gregory Nutt
2020-04-01 10:13:52 -06:00
committed by Alan Carvalho de Assis
parent a7415058e5
commit 9ff1795760
8 changed files with 727 additions and 549 deletions
+107 -72
View File
@@ -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;
}
}
}
+21 -35
View File
@@ -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