Пример #1
0
static void usbmsc_unbind(FAR struct usbdevclass_driver_s *driver, FAR struct usbdev_s *dev)
{
	FAR struct usbmsc_dev_s *priv;
	FAR struct usbmsc_req_s *reqcontainer;
	irqstate_t flags;
	int i;

	usbtrace(TRACE_CLASSUNBIND, 0);

#ifdef CONFIG_DEBUG
	if (!driver || !dev || !dev->ep0) {
		usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_UNBINDINVALIDARGS), 0);
		return;
	}
#endif

	/* Extract reference to private data */

	priv = ((FAR struct usbmsc_driver_s *)driver)->dev;

#ifdef CONFIG_DEBUG
	if (!priv) {
		usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_EP0NOTBOUND1), 0);
		return;
	}
#endif

	/* The worker thread should have already been stopped by the
	 * driver un-initialize logic.
	 */

	DEBUGASSERT(priv->thstate == USBMSC_STATE_TERMINATED || priv->thstate == USBMSC_STATE_NOTSTARTED);

	/* Make sure that we are not already unbound */

	if (priv != NULL) {
		/* Make sure that the endpoints have been unconfigured.  If
		 * we were terminated gracefully, then the configuration should
		 * already have been reset.  If not, then calling usbmsc_resetconfig
		 * should cause the endpoints to immediately terminate all
		 * transfers and return the requests to us (with result == -ESHUTDOWN)
		 */

		usbmsc_resetconfig(priv);
		up_mdelay(50);

		/* Free the pre-allocated control request */

		if (priv->ctrlreq != NULL) {
			usbmsc_freereq(dev->ep0, priv->ctrlreq);
			priv->ctrlreq = NULL;
		}

		/* Free pre-allocated read requests (which should all have
		 * been returned to the free list at this time -- we don't check)
		 */

		for (i = 0; i < CONFIG_USBMSC_NRDREQS; i++) {
			reqcontainer = &priv->rdreqs[i];
			if (reqcontainer->req) {
				usbmsc_freereq(priv->epbulkout, reqcontainer->req);
				reqcontainer->req = NULL;
			}
		}

		/* Free the bulk OUT endpoint */

		if (priv->epbulkout) {
			DEV_FREEEP(dev, priv->epbulkout);
			priv->epbulkout = NULL;
		}

		/* Free write requests that are not in use (which should be all
		 * of them
		 */

		flags = irqsave();
		while (!sq_empty(&priv->wrreqlist)) {
			reqcontainer = (struct usbmsc_req_s *)sq_remfirst(&priv->wrreqlist);
			if (reqcontainer->req != NULL) {
				usbmsc_freereq(priv->epbulkin, reqcontainer->req);
			}
		}

		/* Free the bulk IN endpoint */

		if (priv->epbulkin) {
			DEV_FREEEP(dev, priv->epbulkin);
			priv->epbulkin = NULL;
		}

		irqrestore(flags);
	}
}
Пример #2
0
static void usbclass_unbind(struct usbdevclass_driver_s *driver,
                            struct usbdev_s *dev)
{
    struct apbridge_dev_s *priv;

    usbtrace(TRACE_CLASSUNBIND, 0);

#ifdef CONFIG_DEBUG
    if (!driver || !dev || !dev->ep0) {
        usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0);
        return;
    }
#endif

    /* Extract reference to private data */

    priv = ((struct apbridge_driver_s *)driver)->dev;

#ifdef CONFIG_DEBUG
    if (!priv) {
        usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_EP0NOTBOUND), 0);
        return;
    }
#endif

    /* Make sure that we are not already unbound */

    if (priv != NULL) {
        /* Make sure that the endpoints have been unconfigured.  If
         * we were terminated gracefully, then the configuration should
         * already have been reset.  If not, then calling usbclass_resetconfig
         * should cause the endpoints to immediately terminate all
         * transfers and return the requests to us (with result == -ESHUTDOWN)
         */

        usbclass_resetconfig(priv);
        up_mdelay(50);

        /* Free the interrupt IN endpoint */

        if (priv->epintin) {
            DEV_FREEEP(dev, priv->epintin);
            priv->epintin = NULL;
        }

        /* Free the bulk IN endpoint */

        if (priv->epbulkin) {
            DEV_FREEEP(dev, priv->epbulkin);
            priv->epbulkin = NULL;
        }

        /* Free the pre-allocated control request */

        if (priv->ctrlreq != NULL) {
            usbclass_freereq(dev->ep0, priv->ctrlreq);
            priv->ctrlreq = NULL;
        }

        /* Free the bulk OUT endpoint */

        if (priv->epbulkout) {
            DEV_FREEEP(dev, priv->epbulkout);
            priv->epbulkout = NULL;
        }
    }
}