int usbmsc_unbindlun(FAR void *handle, unsigned int lunno) { FAR struct usbmsc_alloc_s *alloc = (FAR struct usbmsc_alloc_s *)handle; FAR struct usbmsc_dev_s *priv; FAR struct usbmsc_lun_s *lun; int ret; #ifdef CONFIG_DEBUG if (!alloc) { usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_UNBINDLUNINVALIDARGS1), 0); return -EINVAL; } #endif priv = &alloc->dev; #ifdef CONFIG_DEBUG if (!priv->luntab) { usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_INTERNALCONFUSION2), 0); return -EIO; } if (lunno > priv->nluns) { usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_UNBINDLUNINVALIDARGS2), 0); return -EINVAL; } #endif lun = &priv->luntab[lunno]; pthread_mutex_lock(&priv->mutex); #ifdef CONFIG_DEBUG if (lun->inode == NULL) { usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_LUNNOTBOUND), 0); ret = -EBUSY; } else #endif { /* Close the block driver */ usbmsc_lununinitialize(lun); ret = OK; } pthread_mutex_unlock(&priv->mutex); return ret; }
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; #if 0 void *value; #endif int i; #ifdef CONFIG_DEBUG if (!handle) { usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_UNINITIALIZEINVALIDARGS), 0); return; } #endif priv = &alloc->dev; #ifdef CONFIG_USBMSC_COMPOSITE /* Check for pass 2 uninitialization. We did most of the work on the * first pass uninitialization. */ if (priv->thpid == 0) { /* In this second and final pass, all that remains to be done is to * free the memory resources. */ kmm_free(priv); return; } #endif /* If the thread hasn't already exitted, tell it to exit now */ if (priv->thstate != USBMSC_STATE_NOTSTARTED) { /* The thread was started.. Is it still running? */ usbmsc_scsi_lock(priv); if (priv->thstate != USBMSC_STATE_TERMINATED) { /* Yes.. Ask the thread to stop */ flags = irqsave(); priv->theventset |= USBMSC_EVENT_TERMINATEREQUEST; usbmsc_scsi_signal(priv); irqrestore(flags); } usbmsc_scsi_unlock(priv); /* Wait for the thread to exit */ while ((priv->theventset & USBMSC_EVENT_TERMINATEREQUEST) != 0) { usbmsc_sync_wait(priv); } } priv->thpid = 0; /* Unregister the driver (unless we are a part of a composite device) */ #ifndef CONFIG_USBMSC_COMPOSITE usbdev_unregister(&alloc->drvr.drvr); #endif /* Uninitialize and release the LUNs */ for (i = 0; i < priv->nluns; ++i) { usbmsc_lununinitialize(&priv->luntab[i]); } kmm_free(priv->luntab); /* Release the I/O buffer */ if (priv->iobuffer) { kmm_free(priv->iobuffer); } /* Uninitialize and release the driver structure */ sem_destroy(&priv->thsynch); sem_destroy(&priv->thlock); sem_destroy(&priv->thwaitsem); #ifndef CONFIG_USBMSC_COMPOSITE /* For the case of the composite driver, there is a two pass * uninitialization sequence. We cannot yet free the driver structure. * We will do that on the second pass (and we will know that it is the * second pass because of priv->thpid == 0) */ kmm_free(priv); #endif }
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; #ifdef SDCC pthread_addr_t result1, result2; pthread_attr_t attr; #endif void *value; int i; #ifdef CONFIG_DEBUG if (!handle) { usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_UNINITIALIZEINVALIDARGS), 0); return; } #endif priv = &alloc->dev; /* If the thread hasn't already exitted, tell it to exit now */ if (priv->thstate != USBMSC_STATE_NOTSTARTED) { /* The thread was started.. Is it still running? */ pthread_mutex_lock(&priv->mutex); if (priv->thstate != USBMSC_STATE_TERMINATED) { /* Yes.. Ask the thread to stop */ flags = irqsave(); priv->theventset |= USBMSC_EVENT_TERMINATEREQUEST; pthread_cond_signal(&priv->cond); irqrestore(flags); } pthread_mutex_unlock(&priv->mutex); /* Wait for the thread to exit. This is necessary even if the * thread has already exitted in order to collect the join * garbage */ (void)pthread_join(priv->thread, &value); } priv->thread = 0; /* Unregister the driver (unless we are a part of a composite device) */ #ifndef CONFIG_USBMSC_COMPOSITE usbdev_unregister(&alloc->drvr.drvr); #endif /* Uninitialize and release the LUNs */ for (i = 0; i < priv->nluns; ++i) { usbmsc_lununinitialize(&priv->luntab[i]); } kfree(priv->luntab); /* Release the I/O buffer */ if (priv->iobuffer) { kfree(priv->iobuffer); } /* Uninitialize and release the driver structure */ pthread_mutex_destroy(&priv->mutex); pthread_cond_destroy(&priv->cond); kfree(priv); }