This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 59f7fe11a391a5b4d962de6f9fdca31dec398e8e
Author: zhangyuan21 <[email protected]>
AuthorDate: Wed Aug 30 10:53:10 2023 +0800

    usbdev: adb use fs device for ep process
    
    Signed-off-by: zhangyuan21 <[email protected]>
---
 drivers/usbdev/Kconfig |    7 +-
 drivers/usbdev/adb.c   | 1679 ++----------------------------------------------
 2 files changed, 71 insertions(+), 1615 deletions(-)

diff --git a/drivers/usbdev/Kconfig b/drivers/usbdev/Kconfig
index e9b6efd8ea..a8f23d03f9 100644
--- a/drivers/usbdev/Kconfig
+++ b/drivers/usbdev/Kconfig
@@ -590,6 +590,7 @@ endif # CDCACM
 menuconfig USBADB
        bool "USB Android Debug Bridge (ADB) support"
        default n
+       select USBDEV_FS
        ---help---
                Enables USB Android Debug Bridge (ADB) support
 
@@ -717,12 +718,6 @@ config USBADB_INTERFACESTR
        string "Interface descriptor string"
        default "ADB Interface"
 
-config USBADB_NPOLLWAITERS
-       int "Number of ADB poll waiters"
-       default 1
-       ---help---
-               Maximum number of threads that can be waiting on poll().
-
 endif # USBADB
 
 menuconfig USBMSC
diff --git a/drivers/usbdev/adb.c b/drivers/usbdev/adb.c
index 9ee8713275..cad83db225 100644
--- a/drivers/usbdev/adb.c
+++ b/drivers/usbdev/adb.c
@@ -27,13 +27,9 @@
 #include <assert.h>
 #include <errno.h>
 #include <debug.h>
-#include <fcntl.h>
-#include <poll.h>
 
 #include <nuttx/nuttx.h>
 #include <nuttx/kmalloc.h>
-#include <nuttx/queue.h>
-#include <nuttx/mutex.h>
 #include <nuttx/usb/usb.h>
 #include <nuttx/usb/usbdev.h>
 #include <nuttx/usb/usbdev_trace.h>
@@ -44,8 +40,7 @@
 #include <nuttx/board.h>
 #endif
 
-#include <nuttx/usb/composite.h>
-#include "composite.h"
+#include "usbdev_fs.h"
 
 /****************************************************************************
  * Pre-processor Definitions
@@ -53,20 +48,20 @@
 
 /* FIXME use minor for char device npath */
 
-#define USBADB_CHARDEV_PATH "/dev/adb0"
+#define USBADB_CHARDEV_PATH        "/dev/adb0"
 
 /* USB Controller */
 
 #ifdef CONFIG_USBDEV_SELFPOWERED
-#  define USBADB_SELFPOWERED USB_CONFIG_ATTR_SELFPOWER
+#  define USBADB_SELFPOWERED       USB_CONFIG_ATTR_SELFPOWER
 #else
-#  define USBADB_SELFPOWERED (0)
+#  define USBADB_SELFPOWERED       (0)
 #endif
 
 #ifdef CONFIG_USBDEV_REMOTEWAKEUP
-#  define USBADB_REMOTEWAKEUP USB_CONFIG_ATTR_WAKEUP
+#  define USBADB_REMOTEWAKEUP      USB_CONFIG_ATTR_WAKEUP
 #else
-#  define USBADB_REMOTEWAKEUP (0)
+#  define USBADB_REMOTEWAKEUP      (0)
 #endif
 
 /* Buffer big enough for any of our descriptors (the config descriptor is the
@@ -103,140 +98,10 @@
 
 #define USBADB_NCONFIGS            (1)
 
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-/* Manage char device non blocking io */
-
-typedef struct adb_char_waiter_sem_s
-{
-  sem_t sem;
-  FAR struct adb_char_waiter_sem_s *next;
-} adb_char_waiter_sem_t;
-
-/* Container to support a list of requests */
-
-struct usbadb_wrreq_s
-{
-  FAR sq_entry_t node;          /* Implements a singly linked list */
-  FAR struct usbdev_req_s *req; /* The contained request */
-};
-
-struct usbadb_rdreq_s
-{
-  FAR sq_entry_t node;          /* Implements a singly linked list */
-  FAR struct usbdev_req_s *req; /* The contained request */
-  uint16_t offset;              /* Offset to valid data in the RX request */
-};
-
-/* This structure describes the internal state of the driver */
-
-struct usbdev_adb_s
-{
-  FAR struct composite_dev_s *cdev;   /* composite dev pointer */
-  struct usbdev_devinfo_s devinfo;
-
-  FAR struct usbdev_ep_s  *epbulkin;  /* Bulk IN endpoint structure */
-  FAR struct usbdev_ep_s  *epbulkout; /* Bulk OUT endpoint structure */
-
-  struct sq_queue_s txfree;           /* Available write request containers */
-  struct sq_queue_s rxpending;        /* Pending read request containers */
-
-  /* Pre-allocated request containers. The write requests will be
-   * linked in a free list (txfree), and used to send requests to
-   * EPBULKIN; Read requests will be queued in the EBULKOUT.
-   */
-
-  bool registered;                    /* Has register_driver() been called */
-
-  struct usbadb_wrreq_s wrreqs[CONFIG_USBADB_NWRREQS];
-  struct usbadb_rdreq_s rdreqs[CONFIG_USBADB_NRDREQS];
-
-  /* Char device driver */
-
-  mutex_t                lock;     /* Enforces device exclusive access */
-  adb_char_waiter_sem_t *rdsems;   /* List of blocking readers */
-  adb_char_waiter_sem_t *wrsems;   /* List of blocking writers */
-  uint8_t               crefs;     /* Count of opened instances */
-  FAR struct pollfd *fds[CONFIG_USBADB_NPOLLWAITERS];
-};
-
-struct adb_driver_s
-{
-  struct usbdevclass_driver_s drvr;
-  struct usbdev_adb_s dev;
-};
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-/* USB class device *********************************************************/
-
-static int     usbclass_bind(FAR struct usbdevclass_driver_s *driver,
-                 FAR struct usbdev_s *dev);
-static void    usbclass_unbind(FAR struct usbdevclass_driver_s *driver,
-                 FAR struct usbdev_s *dev);
-static int     usbclass_setup(FAR struct usbdevclass_driver_s *driver,
-                 FAR struct usbdev_s *dev,
-                 FAR const struct usb_ctrlreq_s *ctrl, FAR uint8_t *dataout,
-                 size_t outlen);
-static void    usbclass_disconnect(FAR struct usbdevclass_driver_s *driver,
-                 FAR struct usbdev_s *dev);
-
-static void    usbclass_suspend(FAR struct usbdevclass_driver_s *driver,
-                 FAR struct usbdev_s *dev);
-static void    usbclass_resume(FAR struct usbdevclass_driver_s *driver,
-                 FAR struct usbdev_s *dev);
-
-/* Char device Operations ***************************************************/
-
-static int adb_char_open(FAR struct file *filep);
-static int adb_char_close(FAR struct file *filep);
-
-static ssize_t adb_char_read(FAR struct file *filep, FAR char *buffer,
-                               size_t len);
-static ssize_t adb_char_write(FAR struct file *filep,
-                                FAR const char *buffer, size_t len);
-static int adb_char_poll(FAR struct file *filep, FAR struct pollfd *fds,
-                       bool setup);
-
-static void adb_char_notify_readers(FAR struct usbdev_adb_s *priv);
-
-static void adb_char_on_connect(FAR struct usbdev_adb_s *priv, int connect);
-
 /****************************************************************************
  * Private Data
  ****************************************************************************/
 
-/* USB class device *********************************************************/
-
-static const struct usbdevclass_driverops_s g_adb_driverops =
-{
-  usbclass_bind,       /* bind */
-  usbclass_unbind,     /* unbind */
-  usbclass_setup,      /* setup */
-  usbclass_disconnect, /* disconnect */
-  usbclass_suspend,    /* suspend */
-  usbclass_resume      /* resume */
-};
-
-/* Char device **************************************************************/
-
-static const struct file_operations g_adb_fops =
-{
-  adb_char_open,  /* open */
-  adb_char_close, /* close */
-  adb_char_read,  /* read */
-  adb_char_write, /* write */
-  NULL,           /* seek */
-  NULL,           /* ioctl */
-  NULL,           /* mmap */
-  NULL,           /* truncate */
-  adb_char_poll   /* poll */
-};
-
 /* USB descriptor ***********************************************************/
 
 #ifndef CONFIG_USBADB_COMPOSITE
@@ -348,415 +213,54 @@ static const struct usb_ifdesc_s g_adb_ifdesc =
   .iif      = USBADB_INTERFACESTRID
 };
 
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: usbclass_copy_epdesc
- *
- * Description:
- *   Copies the requested Endpoint Description into the buffer given.
- *   Returns the number of Bytes filled in ( sizeof(struct usb_epdesc_s) ).
- *
- ****************************************************************************/
-
-static int usbclass_copy_epdesc(int epid, FAR struct usb_epdesc_s *epdesc,
-                                FAR struct usbdev_devinfo_s *devinfo,
-                                bool hispeed)
+static const struct usbdev_epinfo_s g_adb_epbulkin =
 {
-#ifndef CONFIG_USBDEV_DUALSPEED
-  UNUSED(hispeed);
-#endif
-
-  epdesc->len  = USB_SIZEOF_EPDESC;           /* Descriptor length */
-  epdesc->type = USB_DESC_TYPE_ENDPOINT;      /* Descriptor type */
-  epdesc->attr = USB_EP_ATTR_XFER_BULK |      /* Endpoint attributes */
-                 USB_EP_ATTR_NO_SYNC   |
-                 USB_EP_ATTR_USAGE_DATA;
-  epdesc->interval = 0;                       /* Interval */
-
-  if (epid == USBADB_EP_BULKIN_IDX) /* Bulk IN endpoint */
-    {
-      /* Endpoint address */
-
-      epdesc->addr = USB_EPIN(devinfo->epno[USBADB_EP_BULKIN_IDX]);
-
-#ifdef CONFIG_USBDEV_DUALSPEED
-      if (hispeed)
-        {
-          /* Maximum packet size (high speed) */
-
-          epdesc->mxpacketsize[0] = LSBYTE(CONFIG_USBADB_EPBULKIN_HSSIZE);
-          epdesc->mxpacketsize[1] = MSBYTE(CONFIG_USBADB_EPBULKIN_HSSIZE);
-        }
-      else
-#endif
-        {
-          /* Maximum packet size (full speed) */
-
-          epdesc->mxpacketsize[0] = LSBYTE(CONFIG_USBADB_EPBULKIN_FSSIZE);
-          epdesc->mxpacketsize[1] = MSBYTE(CONFIG_USBADB_EPBULKIN_FSSIZE);
-        }
-    }
-  else /* USBADB_EP_BULKOUT_IDX: Bulk OUT endpoint */
+  .desc =
     {
-      /* Endpoint address */
-
-      epdesc->addr = USB_EPOUT(devinfo->epno[USBADB_EP_BULKOUT_IDX]);
-
+      .len      = USB_SIZEOF_EPDESC,
+      .type     = USB_DESC_TYPE_ENDPOINT,
+      .addr     = USB_DIR_IN,
+      .attr     = USB_EP_ATTR_XFER_BULK |
+                  USB_EP_ATTR_NO_SYNC   |
+                  USB_EP_ATTR_USAGE_DATA,
+      .interval = 0,
+    },
+  .fssize = CONFIG_USBADB_EPBULKIN_FSSIZE,
 #ifdef CONFIG_USBDEV_DUALSPEED
-      if (hispeed)
-        {
-          /* Maximum packet size (high speed) */
-
-          epdesc->mxpacketsize[0] = LSBYTE(CONFIG_USBADB_EPBULKOUT_HSSIZE);
-          epdesc->mxpacketsize[1] = MSBYTE(CONFIG_USBADB_EPBULKOUT_HSSIZE);
-        }
-      else
-#endif
-        {
-          /* Maximum packet size (full speed) */
-
-          epdesc->mxpacketsize[0] = LSBYTE(CONFIG_USBADB_EPBULKOUT_FSSIZE);
-          epdesc->mxpacketsize[1] = MSBYTE(CONFIG_USBADB_EPBULKOUT_FSSIZE);
-        }
-    }
-
-  return sizeof(struct usb_epdesc_s);
-}
-
-/****************************************************************************
- * Name: usb_adb_submit_rdreq
- *
- * Description:
- *   Submits the bulk OUT read request. Takes care not to submit the request
- *   when the RX packet buffer is already in use.
- *
- * Input Parameters:
- *   priv: pointer to ADB device driver structure
- *
- * Returned Value:
- *   The return value of the EP_SUBMIT operation
- *
- ****************************************************************************/
-
-static int usb_adb_submit_rdreq(FAR struct usbdev_adb_s *priv,
-                                FAR struct usbadb_rdreq_s *rdcontainer)
-{
-  FAR struct usbdev_req_s *req;
-  FAR struct usbdev_ep_s *ep;
-  int ret;
-
-  DEBUGASSERT(priv != NULL && rdcontainer != NULL);
-
-  req      = rdcontainer->req;
-  DEBUGASSERT(req != NULL);
-
-  /* Requeue the read request */
-
-  ep       = priv->epbulkout;
-  req->len = ep->maxpacket;
-  ret      = EP_SUBMIT(ep, req);
-  if (ret != OK)
-    {
-      usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_RDSUBMIT),
-                              (uint16_t)-req->result);
-    }
-
-  return ret;
-}
-
-/****************************************************************************
- * Name: usb_adb_wrcomplete
- *
- * Description:
- *   Handle completion of write request.  This function probably executes
- *   in the context of an interrupt handler.
- *
- ****************************************************************************/
-
-static void usb_adb_wrcomplete(FAR struct usbdev_ep_s *ep,
-                               FAR struct usbdev_req_s *req)
-{
-  FAR struct usbadb_wrreq_s *wrcontainer;
-  FAR struct usbdev_adb_s *priv;
-  irqstate_t flags;
-
-  /* Sanity check */
-
-#ifdef CONFIG_DEBUG_FEATURES
-  if (!ep || !ep->priv || !req || !req->priv)
-    {
-      usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0);
-      return;
-    }
+  .hssize = CONFIG_USBADB_EPBULKIN_HSSIZE,
 #endif
+  .reqnum = CONFIG_USBADB_NWRREQS,
+};
 
-  /* Extract references to private data */
-
-  priv        = (FAR struct usbdev_adb_s *)ep->priv;
-  wrcontainer = (FAR struct usbadb_wrreq_s *)req->priv;
-
-  /* Return the write request to the free list */
-
-  flags = enter_critical_section();
-  sq_addlast(&wrcontainer->node, &priv->txfree);
-
-  /* Check for termination condition */
-
-  switch (req->result)
-    {
-    case OK: /* Normal completion */
-      {
-        usbtrace(TRACE_CLASSWRCOMPLETE, sq_count(&priv->txfree));
-
-        /* Notify all waiting writers that write req is available */
-
-        adb_char_waiter_sem_t *cur_sem = priv->wrsems;
-        while (cur_sem != NULL)
-          {
-            nxsem_post(&cur_sem->sem);
-            cur_sem = cur_sem->next;
-          }
-
-        priv->wrsems = NULL;
-
-        /* Notify all poll/select waiters */
-
-        poll_notify(priv->fds, CONFIG_USBADB_NPOLLWAITERS, POLLOUT);
-      }
-      break;
-
-    case -ESHUTDOWN: /* Disconnection */
-      {
-        usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_WRSHUTDOWN),
-                 sq_count(&priv->txfree));
-      }
-      break;
-
-    default: /* Some other error occurred */
-      {
-        usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_WRUNEXPECTED),
-                 (uint16_t)-req->result);
-      }
-      break;
-    }
-
-  leave_critical_section(flags);
-}
-
-/****************************************************************************
- * Name: usb_adb_rdcomplete
- *
- * Description:
- *   Handle completion of read request on the bulk OUT endpoint.
- *
- ****************************************************************************/
-
-static void usb_adb_rdcomplete(FAR struct usbdev_ep_s *ep,
-                               FAR struct usbdev_req_s *req)
+static const struct usbdev_epinfo_s g_adb_epbulkout =
 {
-  FAR struct usbadb_rdreq_s *rdcontainer;
-  FAR struct usbdev_adb_s *priv;
-  irqstate_t flags;
-
-  /* Sanity check */
-
-#ifdef CONFIG_DEBUG_FEATURES
-  if (!ep || !ep->priv || !req)
+  .desc =
     {
-      usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0);
-      return;
-    }
+      .len      = USB_SIZEOF_EPDESC,
+      .type     = USB_DESC_TYPE_ENDPOINT,
+      .addr     = USB_DIR_OUT,
+      .attr     = USB_EP_ATTR_XFER_BULK |
+                  USB_EP_ATTR_NO_SYNC   |
+                  USB_EP_ATTR_USAGE_DATA,
+      .interval = 0,
+    },
+  .fssize = CONFIG_USBADB_EPBULKOUT_FSSIZE,
+#ifdef CONFIG_USBDEV_DUALSPEED
+  .hssize = CONFIG_USBADB_EPBULKOUT_HSSIZE,
 #endif
+  .reqnum = CONFIG_USBADB_NRDREQS,
+};
 
-  /* Extract references to private data */
-
-  priv        = (FAR struct usbdev_adb_s *)ep->priv;
-  rdcontainer = (FAR struct usbadb_rdreq_s *)req->priv;
-
-  /* Process the received data unless this is some unusual condition */
-
-  switch (req->result)
-    {
-    case 0: /* Normal completion */
-
-      usbtrace(TRACE_CLASSRDCOMPLETE, sq_count(&priv->rxpending));
-
-      /* Restart request due to either no reader or
-       * empty frame received.
-       */
-
-      if (priv->crefs == 0)
-        {
-          uwarn("drop frame\n");
-          goto restart_req;
-        }
-
-      if (req->xfrd <= 0)
-        {
-          goto restart_req;
-        }
-
-      /* Queue request and notify readers */
-
-      flags = enter_critical_section();
-
-      /* Put request on RX pending queue */
-
-      rdcontainer->offset = 0;
-      sq_addlast(&rdcontainer->node, &priv->rxpending);
-
-      adb_char_notify_readers(priv);
-
-      leave_critical_section(flags);
-      return;
-
-    case -ESHUTDOWN: /* Disconnection */
-      usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_RDSHUTDOWN), 0);
-      return;
-
-    default: /* Some other error occurred */
-      usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_RDUNEXPECTED),
-               (uint16_t)-req->result);
-      goto restart_req;
-    };
-
-restart_req:
-
-  /* Restart request */
-
-  usb_adb_submit_rdreq(priv, rdcontainer);
-}
-
-/****************************************************************************
- * Name: usbclass_resetconfig
- *
- * Description:
- *   Mark the device as not configured and disable all endpoints.
- *
- ****************************************************************************/
-
-static void usbclass_resetconfig(FAR struct usbdev_adb_s *priv)
+static const FAR struct usbdev_epinfo_s *g_adb_epinfos[USBADB_NUM_EPS] =
 {
-  /* Are we configured? */
-
-  if (priv->cdev->config != COMPOSITE_CONFIGIDNONE)
-    {
-      /* Yes.. but not anymore */
-
-      adb_char_on_connect(priv, 0);
-
-      /* Disable endpoints.  This should force completion of all pending
-       * transfers.
-       */
-
-      EP_DISABLE(priv->epbulkin);
-      EP_DISABLE(priv->epbulkout);
-    }
-}
+  &g_adb_epbulkin,
+  &g_adb_epbulkout,
+};
 
 /****************************************************************************
- * Name: usbclass_setconfig
- *
- * Description:
- *   Set the device configuration by allocating and configuring endpoints and
- *   by allocating and queue read and write requests.
- *
+ * Private Functions
  ****************************************************************************/
 
-static int usbclass_setconfig(FAR struct usbdev_adb_s *priv, uint8_t config)
-{
-  struct usb_epdesc_s epdesc;
-  bool hispeed = false;
-  int i;
-  int ret = 0;
-
-#ifdef CONFIG_DEBUG_FEATURES
-  if (priv == NULL)
-    {
-      usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0);
-      return -EIO;
-    }
-#endif
-
-#ifdef CONFIG_USBDEV_DUALSPEED
-  hispeed = (priv->cdev->usbdev->speed == USB_SPEED_HIGH);
-#endif
-
-  /* Discard the previous configuration data */
-
-  usbclass_resetconfig(priv);
-
-  /* Was this a request to simply discard the current configuration? */
-
-  if (config == COMPOSITE_CONFIGIDNONE)
-    {
-      usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_CONFIGNONE), 0);
-      return 0;
-    }
-
-  /* We only accept one configuration */
-
-  if (config != COMPOSITE_CONFIGID)
-    {
-      usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_CONFIGIDBAD), 0);
-      return -EINVAL;
-    }
-
-  /* Configure the IN bulk endpoint */
-
-  usbclass_copy_epdesc(USBADB_EP_BULKIN_IDX, &epdesc,
-                       &priv->devinfo, hispeed);
-  ret = EP_CONFIGURE(priv->epbulkin, &epdesc, false);
-
-  if (ret < 0)
-    {
-      usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_EPBULKINCONFIGFAIL), 0);
-      goto errout;
-    }
-
-  priv->epbulkin->priv = priv;
-
-  /* Configure the OUT bulk endpoint */
-
-  usbclass_copy_epdesc(USBADB_EP_BULKOUT_IDX, &epdesc,
-                       &priv->devinfo, hispeed);
-  ret = EP_CONFIGURE(priv->epbulkout, &epdesc, true);
-
-  if (ret < 0)
-    {
-      usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_EPBULKOUTCONFIGFAIL), 0);
-      goto errout;
-    }
-
-  priv->epbulkout->priv = priv;
-
-  /* Queue read requests in the bulk OUT endpoint */
-
-  for (i = 0; i < CONFIG_USBADB_NRDREQS; i++)
-    {
-      priv->rdreqs[i].req->callback = usb_adb_rdcomplete;
-      ret = usb_adb_submit_rdreq(priv, &priv->rdreqs[i]);
-      if (ret != OK)
-        {
-          /* TODO cancel submitted requests */
-
-          goto errout;
-        }
-    }
-
-  /* We are successfully configured. Char device is now active */
-
-  adb_char_on_connect(priv, 1);
-  return OK;
-
-errout:
-  usbclass_resetconfig(priv);
-  return ret;
-}
-
 /****************************************************************************
  * Name: usbclass_mkcfgdesc
  *
@@ -794,8 +298,10 @@ static int16_t usbclass_mkcfgdesc(FAR uint8_t *buf,
 
   memcpy(dest, &g_adb_ifdesc, sizeof(g_adb_ifdesc));
 
-  usbclass_copy_epdesc(USBADB_EP_BULKIN_IDX, &epdesc[0], devinfo, hispeed);
-  usbclass_copy_epdesc(USBADB_EP_BULKOUT_IDX, &epdesc[1], devinfo, hispeed);
+  usbdev_copy_epdesc(&epdesc[0], devinfo->epno[USBADB_EP_BULKIN_IDX],
+                     hispeed, &g_adb_epbulkin);
+  usbdev_copy_epdesc(&epdesc[1], devinfo->epno[USBADB_EP_BULKOUT_IDX],
+                     hispeed, &g_adb_epbulkout);
 
 #ifdef CONFIG_USBADB_COMPOSITE
   /* For composite device, apply possible offset to the interface numbers */
@@ -857,1116 +363,71 @@ static int usbclass_mkstrdesc(uint8_t id, FAR struct 
usb_strdesc_s *strdesc)
 }
 
 /****************************************************************************
- * USB Class Driver Methods
+ * Public Functions
  ****************************************************************************/
 
+#ifndef CONFIG_USBADB_COMPOSITE
 /****************************************************************************
- * Name: usbclass_bind
+ * Name: usbdev_adb_initialize
  *
  * Description:
- *   Invoked when the driver is bound to a USB device driver
+ *   Initialize the Android Debug Bridge USB device driver.
+ *
+ * Returned Value:
+ *   A non-NULL "handle" is returned on success.
  *
  ****************************************************************************/
 
-static int usbclass_bind(FAR struct usbdevclass_driver_s *driver,
-                         FAR struct usbdev_s *dev)
+FAR void *usbdev_adb_initialize(void)
 {
-  int ret;
-  int i;
-  uint16_t reqlen;
-  irqstate_t flags;
-  FAR struct usbdev_adb_s *priv = &((FAR struct adb_driver_s *)driver)->dev;
-
-  /* Bind the composite device */
-
-  priv->cdev = dev->ep0->priv;
-
-  /* Pre-allocate all endpoints... the endpoints will not be functional
-   * until the SET CONFIGURATION request is processed in usbclass_setconfig.
-   * This is done here because there may be calls to kmm_malloc and the SET
-   * CONFIGURATION processing probably occurs within interrupt handling
-   * logic where kmm_malloc calls will fail.
-   */
-
-  /* Pre-allocate the IN bulk endpoint */
-
-  priv->epbulkin = DEV_ALLOCEP(dev,
-      USB_EPIN(priv->devinfo.epno[USBADB_EP_BULKIN_IDX]),
-      true,
-      USB_EP_ATTR_XFER_BULK);
-
-  if (!priv->epbulkin)
-    {
-      usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_EPBULKINALLOCFAIL), 0);
-      ret = -ENODEV;
-      goto errout;
-    }
-
-  priv->epbulkin->priv = priv;
-
-  /* Pre-allocate the OUT bulk endpoint */
-
-  priv->epbulkout = DEV_ALLOCEP(dev,
-      USB_EPOUT(priv->devinfo.epno[USBADB_EP_BULKOUT_IDX]),
-      false,
-      USB_EP_ATTR_XFER_BULK);
-
-  if (!priv->epbulkout)
-    {
-      usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_EPBULKOUTALLOCFAIL), 0);
-      ret = -ENODEV;
-      goto errout;
-    }
-
-  priv->epbulkout->priv = priv;
-
-  /* Pre-allocate read requests. The buffer size is one full packet. */
-
-#ifdef CONFIG_USBDEV_DUALSPEED
-  reqlen = CONFIG_USBADB_EPBULKOUT_HSSIZE;
-#else
-  reqlen = CONFIG_USBADB_EPBULKOUT_FSSIZE;
-#endif
-
-  for (i = 0; i < CONFIG_USBADB_NRDREQS; i++)
-    {
-      FAR struct usbadb_rdreq_s *rdcontainer;
-
-      rdcontainer      = &priv->rdreqs[i];
-      rdcontainer->req = usbdev_allocreq(priv->epbulkout, reqlen);
-      if (rdcontainer->req == NULL)
-        {
-          usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_RDALLOCREQ), -ENOMEM);
-          ret = -ENOMEM;
-          goto errout;
-        }
-
-      rdcontainer->offset        = 0;
-      rdcontainer->req->priv     = rdcontainer;
-      rdcontainer->req->callback = usb_adb_rdcomplete;
-    }
-
-  /* Pre-allocate write requests. The buffer size is one full packet. */
-
-#ifdef CONFIG_USBDEV_DUALSPEED
-  reqlen = CONFIG_USBADB_EPBULKIN_HSSIZE;
-#else
-  reqlen = CONFIG_USBADB_EPBULKIN_FSSIZE;
-#endif
+  struct composite_devdesc_s devdesc;
 
-  for (i = 0; i < CONFIG_USBADB_NWRREQS; i++)
-    {
-      FAR struct usbadb_wrreq_s *wrcontainer;
-
-      wrcontainer      = &priv->wrreqs[i];
-      wrcontainer->req = usbdev_allocreq(priv->epbulkin, reqlen);
-      if (wrcontainer->req == NULL)
-        {
-          usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_WRALLOCREQ), -ENOMEM);
-          ret = -ENOMEM;
-          goto errout;
-        }
-
-      wrcontainer->req->priv     = wrcontainer;
-      wrcontainer->req->callback = usb_adb_wrcomplete;
-
-      flags = enter_critical_section();
-      sq_addlast(&wrcontainer->node, &priv->txfree);
-      leave_critical_section(flags);
-    }
+  usbdev_adb_get_composite_devdesc(&devdesc);
 
-  return OK;
+  devdesc.devinfo.epno[USBADB_EP_BULKIN_IDX] =
+    USB_EPNO(CONFIG_USBADB_EPBULKIN);
+  devdesc.devinfo.epno[USBADB_EP_BULKOUT_IDX] =
+    USB_EPNO(CONFIG_USBADB_EPBULKOUT);
 
-errout:
-  usbclass_unbind(driver, dev);
-  return ret;
+  return usbdev_fs_initialize(&g_adb_devdescs, &devdesc);
 }
 
 /****************************************************************************
- * Name: usbclass_unbind
+ * Name: usbdev_adb_uninitialize
  *
  * Description:
- *    Invoked when the driver is unbound from a USB device driver
+ *   Uninitialize the Android Debug Bridge USB device driver.
  *
  ****************************************************************************/
 
-static void usbclass_unbind(FAR struct usbdevclass_driver_s *driver,
-                            FAR struct usbdev_s *dev)
+void usbdev_adb_uninitialize(FAR void *handle)
 {
-  FAR struct usbdev_adb_s *priv;
-  int i;
-
-#ifdef CONFIG_DEBUG_FEATURES
-  if (!driver || !dev || !dev->ep0)
-    {
-      usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0);
-      return;
-    }
-#endif
-
-  /* Extract reference to private data */
-
-  priv = &((FAR struct adb_driver_s *)driver)->dev;
-
-#ifdef CONFIG_DEBUG_FEATURES
-  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);
-
-      /* Free write requests that are not in use (which should be all
-       * of them
-       */
-
-      for (i = 0; i < CONFIG_USBADB_NRDREQS; i++)
-        {
-          FAR struct usbadb_rdreq_s *rdcontainer;
-
-          rdcontainer = &priv->rdreqs[i];
-          if (rdcontainer->req != NULL)
-            {
-              usbdev_freereq(priv->epbulkout, rdcontainer->req);
-            }
-        }
-
-      for (i = 0; i < CONFIG_USBADB_NWRREQS; i++)
-        {
-          FAR struct usbadb_wrreq_s *wrcontainer;
-
-          wrcontainer = &priv->wrreqs[i];
-          if (wrcontainer->req != NULL)
-            {
-              usbdev_freereq(priv->epbulkin, wrcontainer->req);
-            }
-        }
-
-      /* Free the bulk IN endpoint */
-
-      if (priv->epbulkin)
-        {
-          DEV_FREEEP(dev, priv->epbulkin);
-          priv->epbulkin = NULL;
-        }
-
-      /* Free the bulk OUT endpoint */
-
-      if (priv->epbulkout)
-        {
-          DEV_FREEEP(dev, priv->epbulkout);
-          priv->epbulkout = NULL;
-        }
-    }
-}
-
-/****************************************************************************
- * Name: usbclass_setup
- *
- * Description:
- *   Invoked for ep0 control requests.  This function probably executes
- *   in the context of an interrupt handler.
- *
- ****************************************************************************/
-
-static int usbclass_setup(FAR struct usbdevclass_driver_s *driver,
-                          FAR struct usbdev_s *dev,
-                          FAR const struct usb_ctrlreq_s *ctrl,
-                          FAR uint8_t *dataout, size_t outlen)
-{
-  FAR struct usbdev_adb_s *priv;
-  uint16_t value;
-  int ret = -EOPNOTSUPP;
-
-#ifdef CONFIG_DEBUG_FEATURES
-  if (!driver || !dev || !dev->ep0 || !ctrl)
-    {
-      usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0);
-      return -EIO;
-    }
-#endif
-
-  /* Extract reference to private data */
-
-  priv = &((FAR struct adb_driver_s *)driver)->dev;
-
-#ifdef CONFIG_DEBUG_FEATURES
-  if (!priv)
-    {
-      usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_EP0NOTBOUND), 0);
-      return -ENODEV;
-    }
-#endif
-
-  /* Extract the little-endian 16-bit values to host order */
-
-  value = GETUINT16(ctrl->value);
-
-  switch (ctrl->type & USB_REQ_TYPE_MASK)
-    {
-      case USB_REQ_TYPE_STANDARD:
-        {
-          switch (ctrl->req)
-            {
-            case USB_REQ_SETCONFIGURATION:
-              {
-                if (ctrl->type == 0)
-                  {
-                    ret = usbclass_setconfig(priv, value);
-                  }
-              }
-              break;
-
-            default:
-              usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_UNSUPPORTEDSTDREQ),
-                       ctrl->req);
-              break;
-            }
-        }
-        break;
-
-      case USB_REQ_TYPE_CLASS:
-        {
-          /* ADB-Specific Requests */
-
-          usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_UNSUPPORTEDCLASSREQ),
-                   ctrl->req);
-          break;
-        }
-
-      default:
-        {
-          usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_UNSUPPORTEDTYPE),
-                   ctrl->type);
-        }
-    }
-
-  /* Returning a negative value will cause a STALL */
-
-  return ret;
-}
-
-/****************************************************************************
- * Name: usbclass_disconnect
- *
- * Description:
- *   Invoked after all transfers have been stopped, when the host is
- *   disconnected.  This function is probably called from the context of an
- *   interrupt handler.
- *
- ****************************************************************************/
-
-static void usbclass_disconnect(FAR struct usbdevclass_driver_s *driver,
-                                FAR struct usbdev_s *dev)
-{
-  FAR struct usbdev_adb_s *priv;
-
-  usbtrace(TRACE_CLASSDISCONNECT, 0);
-
-#ifdef CONFIG_DEBUG_FEATURES
-  if (!driver || !dev || !dev->ep0)
-    {
-      usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0);
-      return;
-    }
-#endif
-
-  /* Extract reference to private data */
-
-  priv = &((FAR struct adb_driver_s *)driver)->dev;
-
-#ifdef CONFIG_DEBUG_FEATURES
-  if (!priv)
-    {
-      usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_EP0NOTBOUND), 0);
-      return;
-    }
-#endif
-
-  /* Reset the configuration */
-
-  usbclass_resetconfig(priv);
-}
-
-/****************************************************************************
- * Name: usbclass_suspend
- *
- * Description:
- *   Handle the USB suspend event.
- *
- ****************************************************************************/
-
-static void usbclass_suspend(FAR struct usbdevclass_driver_s *driver,
-                             FAR struct usbdev_s *dev)
-{
-  FAR struct usbdev_adb_s *priv = &((FAR struct adb_driver_s *)driver)->dev;
-
-  usbtrace(TRACE_CLASSSUSPEND, 0);
-
-  adb_char_on_connect(priv, 0);
-}
-
-/****************************************************************************
- * Name: usbclass_resume
- *
- * Description:
- *   Handle the USB resume event.
- *
- ****************************************************************************/
-
-static void usbclass_resume(FAR struct usbdevclass_driver_s *driver,
-                            FAR struct usbdev_s *dev)
-{
-  FAR struct usbdev_adb_s *priv = &((FAR struct adb_driver_s *)driver)->dev;
-
-  usbtrace(TRACE_CLASSRESUME, 0);
-
-  adb_char_on_connect(priv, 1);
-}
-
-/****************************************************************************
- * Name: usbclass_classobject
- *
- * Description:
- *   Register USB driver and return the class object.
- *
- * Returned Value:
- *   0 on success, negative error code on failure.
- *
- ****************************************************************************/
-
-static int usbclass_classobject(int minor,
-                                FAR struct usbdev_devinfo_s *devinfo,
-                                FAR struct usbdevclass_driver_s **classdev)
-{
-  int ret;
-  FAR struct adb_driver_s *alloc;
-
-  alloc = (FAR struct adb_driver_s *)
-    kmm_zalloc(sizeof(struct adb_driver_s));
-
-  if (!alloc)
-    {
-      usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_ALLOCDEVSTRUCT), 0);
-      return -ENOMEM;
-    }
-
-  /* Initialize the USB class driver structure */
-
-  alloc->drvr.ops = &g_adb_driverops;
-
-  sq_init(&alloc->dev.rxpending);
-  sq_init(&alloc->dev.txfree);
-
-  /* Save the caller provided device description */
-
-  memcpy(&alloc->dev.devinfo, devinfo,
-         sizeof(struct usbdev_devinfo_s));
-
-  /* Initialize the char device structure */
-
-  nxmutex_init(&alloc->dev.lock);
-  alloc->dev.crefs = 0;
-
-  /* Register char device driver */
-
-  /* FIXME use minor in device name */
-
-  ret = register_driver(USBADB_CHARDEV_PATH, &g_adb_fops, 0666, &alloc->dev);
-  if (ret < 0)
-    {
-      uerr("Failed to register char device");
-      goto exit_free_driver;
-    }
-
-  alloc->dev.registered = true;
-  *classdev = &alloc->drvr;
-  return OK;
-
-exit_free_driver:
-  nxmutex_destroy(&alloc->dev.lock);
-  kmm_free(alloc);
-  return ret;
-}
-
-/****************************************************************************
- * Name: usbclass_uninitialize
- *
- * Description:
- *   Free allocated memory
- *
- * Returned Value:
- *   0 on success, negative error code on failure.
- *
- ****************************************************************************/
-
-static void usbclass_uninitialize(FAR struct usbdevclass_driver_s *classdev)
-{
-  FAR struct adb_driver_s *alloc = container_of(
-    classdev, FAR struct adb_driver_s, drvr);
-
-  #warning FIXME Maybe missing logic here
-  if (!alloc->dev.registered)
-    {
-      if (alloc->dev.crefs == 0)
-        {
-#ifdef CONFIG_USBADB_COMPOSITE
-          kmm_free(alloc);
-#endif
-        }
-
-      return;
-    }
-
-  unregister_driver(USBADB_CHARDEV_PATH);
-
-  if (alloc->dev.registered)
-    {
-      alloc->dev.registered = false;
-#ifndef CONFIG_USBADB_COMPOSITE
-      kmm_free(alloc);
-#endif
-      return;
-    }
-}
-
-/****************************************************************************
- * Char Device Driver Methods
- ****************************************************************************/
-
-/****************************************************************************
- * Name: adb_char_notify_readers
- *
- * Description:
- *   Notify threads waiting to read device. This function must be called
- *   with interrupt disabled.
- *
- ****************************************************************************/
-
-static void adb_char_notify_readers(FAR struct usbdev_adb_s *priv)
-{
-  /* Notify all of the waiting readers */
-
-  adb_char_waiter_sem_t *cur_sem = priv->rdsems;
-  while (cur_sem != NULL)
-    {
-      nxsem_post(&cur_sem->sem);
-      cur_sem = cur_sem->next;
-    }
-
-  priv->rdsems = NULL;
-
-  /* Notify all poll/select waiters */
-
-  poll_notify(priv->fds, CONFIG_USBADB_NPOLLWAITERS, POLLIN);
-}
-
-/****************************************************************************
- * Name: adb_char_open
- *
- * Description:
- *   Open adb device. Only one open() instance is supported.
- *
- ****************************************************************************/
-
-static int adb_char_open(FAR struct file *filep)
-{
-  FAR struct inode *inode = filep->f_inode;
-  FAR struct usbdev_adb_s *priv = inode->i_private;
-  int ret;
-
-  /* Get exclusive access to the device structures */
-
-  ret = nxmutex_lock(&priv->lock);
-  if (ret < 0)
-    {
-      return ret;
-    }
-
-  finfo("entry: <%s> %d\n", inode->i_name, priv->crefs);
-
-  priv->crefs += 1;
-
-  assert(priv->crefs != 0);
-
-  nxmutex_unlock(&priv->lock);
-  return ret;
-}
-
-/****************************************************************************
- * Name: adb_char_close
- *
- * Description:
- *   Close adb device.
- *
- ****************************************************************************/
-
-static int adb_char_close(FAR struct file *filep)
-{
-  int ret;
-  FAR struct inode *inode = filep->f_inode;
-  FAR struct usbdev_adb_s *priv = inode->i_private;
-
-  /* Get exclusive access to the device structures */
-
-  ret = nxmutex_lock(&priv->lock);
-  if (ret < 0)
-    {
-      return ret;
-    }
-
-  finfo("entry: <%s> %d\n", inode->i_name, priv->crefs);
-
-  priv->crefs -= 1;
-
-  assert(priv->crefs >= 0);
-
-  nxmutex_unlock(&priv->lock);
-  return OK;
-}
-
-/****************************************************************************
- * Name: adb_char_blocking_io
- *
- * Description:
- *   Handle read/write blocking io.
- *
- ****************************************************************************/
-
-static int adb_char_blocking_io(FAR struct usbdev_adb_s *priv,
-                                FAR adb_char_waiter_sem_t *sem,
-                                FAR adb_char_waiter_sem_t **slist,
-                                FAR struct sq_queue_s *queue)
-{
-  int ret;
-  irqstate_t flags;
-
-  flags = enter_critical_section();
-
-  if (!sq_empty(queue))
-    {
-      /* Queue not empty after all */
-
-      leave_critical_section(flags);
-      return 0;
-    }
-
-  /* Register waiter semaphore */
-
-  sem->next = *slist;
-  *slist = sem;
-
-  leave_critical_section(flags);
-
-  nxmutex_unlock(&priv->lock);
-
-  /* Wait for USB device to notify */
-
-  ret = nxsem_wait(&sem->sem);
-
-  if (ret < 0)
-    {
-      /* Interrupted wait, unregister semaphore
-       * TODO ensure that lock wait does not fail (ECANCELED)
-       */
-
-      nxmutex_lock(&priv->lock);
-
-      flags = enter_critical_section();
-
-      adb_char_waiter_sem_t *cur_sem = *slist;
-
-      if (cur_sem == sem)
-        {
-          *slist = sem->next;
-        }
-      else
-        {
-          while (cur_sem)
-            {
-              if (cur_sem->next == sem)
-                {
-                  cur_sem->next = sem->next;
-                  break;
-                }
-            }
-        }
-
-      leave_critical_section(flags);
-      nxmutex_unlock(&priv->lock);
-      return ret;
-    }
-
-  return nxmutex_lock(&priv->lock);
-}
-
-/****************************************************************************
- * Name: adb_char_read
- *
- * Description:
- *   Read adb device.
- *
- ****************************************************************************/
-
-static ssize_t adb_char_read(FAR struct file *filep, FAR char *buffer,
-                             size_t len)
-{
-  FAR struct inode *inode = filep->f_inode;
-  FAR struct usbdev_adb_s *priv = inode->i_private;
-  ssize_t ret;
-  size_t retlen;
-  irqstate_t flags;
-
-  assert(len > 0 && buffer != NULL);
-
-  if (priv->cdev->config == COMPOSITE_CONFIGIDNONE)
-    {
-      /* USB device not connected */
-
-      return -EPIPE;
-    }
-
-  ret = nxmutex_lock(&priv->lock);
-  if (ret < 0)
-    {
-      return ret;
-    }
-
-  /* Check for available data */
-
-  if (sq_empty(&priv->rxpending))
-    {
-      if (filep->f_oflags & O_NONBLOCK)
-        {
-          nxmutex_unlock(&priv->lock);
-          return -EAGAIN;
-        }
-
-      adb_char_waiter_sem_t sem;
-      nxsem_init(&sem.sem, 0, 0);
-
-      do
-        {
-          /* RX queue seems empty. Check again with interrupts disabled */
-
-          ret = adb_char_blocking_io(
-            priv, &sem, &priv->rdsems, &priv->rxpending);
-          if (ret < 0)
-            {
-              nxsem_destroy(&sem.sem);
-              return ret;
-            }
-        }
-      while (sq_empty(&priv->rxpending));
-
-      /* RX queue not empty and lock locked so we are the only reader */
-
-      nxsem_destroy(&sem.sem);
-    }
-
-  /* Device ready for read */
-
-  retlen = 0;
-
-  while (!sq_empty(&priv->rxpending) && len > 0)
-    {
-      FAR struct usbadb_rdreq_s *rdcontainer;
-      uint16_t reqlen;
-
-      /* Process each packet in the priv->rxpending list */
-
-      rdcontainer = container_of(
-        sq_peek(&priv->rxpending),
-        struct usbadb_rdreq_s,
-        node);
-
-      reqlen = rdcontainer->req->xfrd - rdcontainer->offset;
-
-      if (reqlen > len)
-        {
-          /* Output buffer full */
-
-          memcpy(&buffer[retlen],
-                 &rdcontainer->req->buf[rdcontainer->offset],
-                 len);
-          rdcontainer->offset += len;
-          retlen += len;
-          break;
-        }
-
-      memcpy(&buffer[retlen],
-             &rdcontainer->req->buf[rdcontainer->offset],
-             reqlen);
-      retlen += reqlen;
-      len -= reqlen;
-
-      /* The entire packet was processed and may be removed from the
-       * pending RX list.
-       */
-
-      /* FIXME use atomic queue primitives ? */
-
-      flags = enter_critical_section();
-      sq_remfirst(&priv->rxpending);
-      leave_critical_section(flags);
-
-      ret = usb_adb_submit_rdreq(priv, rdcontainer);
-
-      if (ret != OK)
-        {
-          /* TODO handle error */
-
-          PANIC();
-        }
-    }
-
-  nxmutex_unlock(&priv->lock);
-  return retlen;
-}
-
-/****************************************************************************
- * Name: adb_char_write
- *
- * Description:
- *   Write adb device.
- *
- ****************************************************************************/
-
-static ssize_t adb_char_write(FAR struct file *filep,
-                                FAR const char *buffer, size_t len)
-{
-  int ret;
-  int wlen;
-  FAR struct usbdev_req_s *req;
-  FAR struct usbadb_wrreq_s *wrcontainer;
-  FAR struct inode *inode = filep->f_inode;
-  FAR struct usbdev_adb_s *priv = inode->i_private;
-
-  irqstate_t flags;
-
-  if (priv->cdev->config == COMPOSITE_CONFIGIDNONE)
-    {
-      /* USB device not connected */
-
-      return -EPIPE;
-    }
-
-  ret = nxmutex_lock(&priv->lock);
-  if (ret < 0)
-    {
-      return ret;
-    }
-
-  /* Check for available write request */
-
-  if (sq_empty(&priv->txfree))
-    {
-      if (filep->f_oflags & O_NONBLOCK)
-        {
-          ret = -EAGAIN;
-          goto errout;
-        }
-
-      adb_char_waiter_sem_t sem;
-      nxsem_init(&sem.sem, 0, 0);
-
-      do
-        {
-          /* TX queue seems empty. Check again with interrupts disabled */
-
-          ret = adb_char_blocking_io(
-            priv, &sem, &priv->wrsems, &priv->txfree);
-          if (ret < 0)
-            {
-              nxsem_destroy(&sem.sem);
-              return ret;
-            }
-        }
-      while (sq_empty(&priv->txfree));
-
-      nxsem_destroy(&sem.sem);
-    }
-
-  /* Device ready for write */
-
-  wlen = 0;
-
-  while (len > 0 && !sq_empty(&priv->txfree))
-    {
-      int cur_len;
-
-      /* Get available TX request slot */
-
-      flags = enter_critical_section();
-
-      wrcontainer = container_of(
-        sq_remfirst(&priv->txfree),
-        struct usbadb_wrreq_s,
-        node);
-
-      leave_critical_section(flags);
-
-      req = wrcontainer->req;
-
-      /* Fill the request with data */
-
-      if (len > priv->epbulkin->maxpacket)
-        {
-          cur_len = priv->epbulkin->maxpacket;
-        }
-      else
-        {
-          cur_len = len;
-        }
-
-      memcpy(req->buf, &buffer[wlen], cur_len);
-
-      /* Then submit the request to the endpoint */
-
-      req->len     = cur_len;
-      req->flags   = 0;
-      req->priv    = wrcontainer;
-      ret          = EP_SUBMIT(priv->epbulkin, req);
-
-      if (ret != OK)
-        {
-          /* TODO add tx request back in txfree queue */
-
-          usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_SUBMITFAIL),
-                   (uint16_t)-ret);
-          PANIC();
-          break;
-        }
-
-      wlen += cur_len;
-      len -= cur_len;
-    }
-
-  assert(wlen > 0);
-  ret = wlen;
-
-errout:
-  nxmutex_unlock(&priv->lock);
-  return ret;
-}
-
-static int adb_char_poll(FAR struct file *filep, FAR struct pollfd *fds,
-                       bool setup)
-{
-  FAR struct inode *inode = filep->f_inode;
-  FAR struct usbdev_adb_s *priv = inode->i_private;
-  int ret;
-  int i;
-  pollevent_t eventset;
-  irqstate_t flags;
-
-  ret = nxmutex_lock(&priv->lock);
-  if (ret < 0)
-    {
-      return ret;
-    }
-
-  ret = OK;
-
-  if (!setup)
-    {
-      /* This is a request to tear down the poll. */
-
-      FAR struct pollfd **slot = (FAR struct pollfd **)fds->priv;
-
-      /* Remove all memory of the poll setup */
-
-      *slot     = NULL;
-      fds->priv = NULL;
-      goto errout;
-    }
-
-  /* FIXME only parts of this function required interrupt disabled */
-
-  flags = enter_critical_section();
-
-  /* This is a request to set up the poll. Find an available
-   * slot for the poll structure reference
-   */
-
-  for (i = 0; i < CONFIG_USBADB_NPOLLWAITERS; i++)
-    {
-      /* Find an available slot */
-
-      if (!priv->fds[i])
-        {
-          /* Bind the poll structure and this slot */
-
-          priv->fds[i] = fds;
-          fds->priv   = &priv->fds[i];
-          break;
-        }
-    }
-
-  if (i >= CONFIG_USBADB_NPOLLWAITERS)
-    {
-      fds->priv = NULL;
-      ret       = -EBUSY;
-      goto exit_leave_critical;
-    }
-
-  eventset = 0;
-
-  /* Notify the POLLOUT event if at least one request is available */
-
-  if (!sq_empty(&priv->txfree))
-    {
-      eventset |= POLLOUT;
-    }
-
-  /* Notify the POLLIN event if at least one read request is pending */
-
-  if (!sq_empty(&priv->rxpending))
-    {
-      eventset |= POLLIN;
-    }
-
-  poll_notify(priv->fds, CONFIG_USBADB_NPOLLWAITERS, eventset);
-
-exit_leave_critical:
-  leave_critical_section(flags);
-errout:
-  nxmutex_unlock(&priv->lock);
-  return ret;
-}
-
-static void adb_char_on_connect(FAR struct usbdev_adb_s *priv, int connect)
-{
-  irqstate_t flags;
-  adb_char_waiter_sem_t *cur_sem;
-
-  flags = enter_critical_section();
-
-  if (connect)
-    {
-      /* Notify poll/select with POLLIN */
-
-      poll_notify(priv->fds, CONFIG_USBADB_NPOLLWAITERS, POLLIN);
-    }
-  else
-    {
-      /* Notify all of the char device waiting readers */
-
-      cur_sem = priv->rdsems;
-      while (cur_sem != NULL)
-        {
-          nxsem_post(&cur_sem->sem);
-          cur_sem = cur_sem->next;
-        }
-
-      priv->rdsems = NULL;
-
-      /* Notify all of the char device waiting writers */
-
-      cur_sem = priv->wrsems;
-      while (cur_sem != NULL)
-        {
-          nxsem_post(&cur_sem->sem);
-          cur_sem = cur_sem->next;
-        }
-
-      priv->wrsems = NULL;
-
-      /* Notify all poll/select waiters that a hangup occurred */
-
-      poll_notify(priv->fds, CONFIG_USBADB_NPOLLWAITERS, POLLERR | POLLHUP);
-    }
-
-    leave_critical_section(flags);
-}
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-#ifndef CONFIG_USBADB_COMPOSITE
-/****************************************************************************
- * Name: usbdev_adb_initialize
- *
- * Description:
- *   Initialize the Android Debug Bridge USB device driver.
- *
- * Returned Value:
- *   A non-NULL "handle" is returned on success.
- *
- ****************************************************************************/
-
-FAR void *usbdev_adb_initialize(void)
-{
-  struct composite_devdesc_s devdesc;
-
-  usbdev_adb_get_composite_devdesc(&devdesc);
-  return composite_initialize(&g_adb_devdescs, &devdesc, 1);
-}
-
-/****************************************************************************
- * Name: usbdev_adb_uninitialize
- *
- * Description:
- *   Uninitialize the Android Debug Bridge USB device driver.
- *
- ****************************************************************************/
-
-void usbdev_adb_uninitialize(FAR void *handle)
-{
-  composite_uninitialize(handle);
+  usbdev_fs_uninitialize(handle);
 }
 #endif
 
 /****************************************************************************
  * Name: usbdev_adb_get_composite_devdesc
  *
- * Description:
- *   Helper function to fill in some constants into the composite
- *   configuration struct.
- *
- * Input Parameters:
- *     dev - Pointer to the configuration struct we should fill
- *
  * Returned Value:
  *   None
  *
  ****************************************************************************/
 
-void usbdev_adb_get_composite_devdesc(struct composite_devdesc_s *dev)
+void usbdev_adb_get_composite_devdesc(FAR struct composite_devdesc_s *dev)
 {
   memset(dev, 0, sizeof(struct composite_devdesc_s));
 
-  dev->mkconfdesc          = usbclass_mkcfgdesc;
-  dev->mkstrdesc           = usbclass_mkstrdesc;
-  dev->classobject         = usbclass_classobject;
-  dev->uninitialize        = usbclass_uninitialize;
+  dev->classobject         = usbdev_fs_classobject;
+  dev->uninitialize        = usbdev_fs_classuninitialize;
+  dev->mkconfdesc          = usbclass_mkcfgdesc,
+  dev->mkstrdesc           = usbclass_mkstrdesc,
   dev->nconfigs            = USBADB_NCONFIGS;
   dev->configid            = 1;
   dev->cfgdescsize         = sizeof(g_adb_ifdesc) + 2 * USB_SIZEOF_EPDESC;
   dev->devinfo.ninterfaces = 1;
   dev->devinfo.nstrings    = USBADB_NSTRIDS;
   dev->devinfo.nendpoints  = USBADB_NUM_EPS;
-
-  /* Default endpoint indexes, board-specific logic can override these */
-
-#ifndef CONFIG_USBADB_COMPOSITE
-  dev->devinfo.epno[USBADB_EP_BULKIN_IDX] =
-    USB_EPNO(CONFIG_USBADB_EPBULKIN);
-  dev->devinfo.epno[USBADB_EP_BULKOUT_IDX] =
-    USB_EPNO(CONFIG_USBADB_EPBULKOUT);
-#endif
+  dev->devinfo.epinfos     = g_adb_epinfos;
+  dev->devinfo.name        = USBADB_CHARDEV_PATH;
 }

Reply via email to