diff --git a/ChangeLog b/ChangeLog
index e6dc2994f1f1ec85e23f45233191818251944a23..d123596312551883eb15345f378ab7d541c4604c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -5417,4 +5417,7 @@
 	* arch/arm/src/stm32/stm32_i2c.c:  Correct an error that crept into
 	  the STM32 F1 I2C driver with some recent changes.  From Yiran Liao
 	  (2013-8-18).
-
+	* drivers/usbhost/usbhost_devaddr.c and include/nuttx/usb/usbhost_devaddr.h:
+	  Add logic for management of device addresses.  This logic does not
+	  currently hook into into anything.  It will someday be a part of the
+	  NuttX USB hub implementation (2013-8-18).
diff --git a/arch/arm/src/sama5/chip/sam_ehci.h b/arch/arm/src/sama5/chip/sam_ehci.h
index 15d8d58abc333a2625819dc1b0a70aa8d505b4a4..9d1282e309b0c441d7f5efb711c992bc940e9d58 100644
--- a/arch/arm/src/sama5/chip/sam_ehci.h
+++ b/arch/arm/src/sama5/chip/sam_ehci.h
@@ -64,7 +64,7 @@
  * However, for the case of the SAMA5 EHCI, we know apriori that the value
  * of 'caplength' is 0x10.  We keep this structure, however, to faciltate
  * porting this driver to other environments where, perhaps, such knowledge
- * is not availaable.
+ * is not available.
  */
 
 /* Host Controller Capability Registers */
diff --git a/drivers/usbhost/Make.defs b/drivers/usbhost/Make.defs
index ebb52269502e0df1d1ba6fa11244e124b9c8838e..ac9eba6a64612c36d258f3d8f2fca4172f1cd2e8 100644
--- a/drivers/usbhost/Make.defs
+++ b/drivers/usbhost/Make.defs
@@ -41,11 +41,12 @@ ifeq ($(CONFIG_USBHOST),y)
 
 CSRCS  += usbhost_registry.c usbhost_registerclass.c usbhost_findclass.c
 CSRCS  += usbhost_enumerate.c usbhost_storage.c usbhost_hidkbd.c
+CSRCS  += usbhost_devaddr.c
 
 # Include add-on USB host driver logic (see misc/drivers)
 
 ifeq ($(CONFIG_NET),y)
-  RTL8187_CSRC  := ${shell if [ -f usbhost$(DELIM)rtl8187x.c ]; then echo "rtl8187x.c"; fi}
+  RTL8187_CSRC := ${shell if [ -f usbhost$(DELIM)rtl8187x.c ]; then echo "rtl8187x.c"; fi}
   CSRCS += $(RTL8187_CSRC)
 endif
 endif
diff --git a/drivers/usbhost/usbhost_devaddr.c b/drivers/usbhost/usbhost_devaddr.c
new file mode 100755
index 0000000000000000000000000000000000000000..95523f78ef1c3646e7b5059496bf64802de8be72
--- /dev/null
+++ b/drivers/usbhost/usbhost_devaddr.c
@@ -0,0 +1,333 @@
+/*******************************************************************************
+ * drivers/usbhost/usbhost_devaddr.c
+ * Manage USB device addresses
+ *
+ *   Copyright (C) 2013 Gregory Nutt. All rights reserved.
+ *   Authors: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * 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
+ *******************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <string.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/kmalloc.h>
+#include <nuttx/usb/usbhost_devaddr.h>
+
+/*******************************************************************************
+ * Pre-processor Definitions
+ *******************************************************************************/
+
+/*******************************************************************************
+ * Private Functions
+ *******************************************************************************/
+
+/****************************************************************************
+ * Name: usbhost_takesem and usbhost_givesem
+ *
+ * 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 usbhost_takesem(FAR struct usbhost_devaddr_s *hcd)
+{
+  /* Take the semaphore (perhaps waiting) */
+
+  while (sem_wait(&hcd->exclsem) != 0)
+    {
+      /* The only case that an error should occr here is if the wait was
+       * awakened by a signal.
+       */
+
+      ASSERT(errno == EINTR);
+    }
+}
+
+#define usbhost_givesem(hcd) sem_post(&hcd->exclsem)
+
+/*******************************************************************************
+ * Name: usbhost_devaddr_hash
+ *
+ * Description:
+ *   Create a hash value from a device address.
+ *
+ *******************************************************************************/
+
+static inline uint8_t usbhost_devaddr_hash(uint8_t devaddr)
+{
+  uint8_t ret = devaddr;
+
+  ret ^= (devaddr >> 2);
+  ret ^= (devaddr >> 3);
+  return ret & USBHOST_DEVADDR_HASHMASK;
+}
+
+/*******************************************************************************
+ * Name: usbhost_devaddr_allocate
+ *
+ * Description:
+ *   Allocate a new unique device address for this HCD.
+ *
+ * Assumptions:
+ *   Caller hold the exclsem
+ *
+ *******************************************************************************/
+
+static int usbhost_devaddr_allocate(FAR struct usbhost_devaddr_s *hcd)
+{
+  uint8_t startaddr = hcd->next;
+  uint8_t devaddr;
+  int index;
+  int bitno;
+
+  /* Loop until we find a valid device address */
+
+  for (;;)
+    {
+      /* Try the next device address */
+
+      devaddr = hcd->next;
+      if (hcd->next >= 0x7f)
+        {
+          hcd->next = 1;
+        }
+      else
+        {
+          hcd->next++;
+        }
+
+      /* Is this address already allocated? */
+
+      index = devaddr >> 5;
+      bitno = devaddr & 0x1f;
+      if ((hcd->alloctab[index] & (1 << bitno)) == 0)
+        {
+          /* No... allocate it now */
+
+          hcd->alloctab[index] |= (1 << bitno);
+          return (int)devaddr;
+        }
+
+      /* This address has already been allocated.  The followign logic will
+       * prevent (unexpected) infinite loops.
+       */
+
+      if (startaddr == devaddr)
+        {
+          /* We are back where we started... the are no free device address */
+
+          return -ENOMEM;
+        }
+    }
+}
+
+/*******************************************************************************
+ * Public Functions
+ *******************************************************************************/
+
+/*******************************************************************************
+ * Name: usbhost_devaddr_initialize
+ *
+ * Description:
+ *   Initialize the caller provided struct usbhost_devaddr_s instance in
+ *   preparation for the management of device addresses on behalf of an HCD.
+ *
+ *******************************************************************************/
+
+void usbhost_devaddr_initialize(FAR struct usbhost_devaddr_s *hcd)
+{
+  DEBUGASSERT(hcd);
+
+  memset(hcd, 0, sizeof(struct usbhost_devaddr_s));
+  sem_init(&hcd->exclsem, 0, 1);
+  hcd->next = 1;
+}
+
+/*******************************************************************************
+ * Name: usbhost_devaddr_create
+ *
+ * Description:
+ *   Create a new unique device address for this HCD.  Bind the void* arg to the
+ *   the device address and return the newly allocated device address.
+ *
+ *******************************************************************************/
+
+int usbhost_devaddr_create(FAR struct usbhost_devaddr_s *hcd,
+                           FAR void *associate)
+{
+  FAR struct usbhost_devhash_s *hentry;
+  uint8_t hvalue;
+  int devaddr;
+
+  /* Allocate a hash table entry */
+
+  hentry = (FAR struct usbhost_devhash_s *)kmalloc(sizeof(struct usbhost_devhash_s));
+  if (!hentry)
+    {
+      udbg("ERROR: Failed to allocate a hash table entry\n");
+      return -ENOMEM;
+    }
+
+  /* Get exclusive access to the HCD device address data */
+
+  usbhost_takesem(hcd);
+
+  /* Allocate a device address */
+
+  devaddr = usbhost_devaddr_allocate(hcd);
+  if (devaddr < 0)
+    {
+      udbg("ERROR: Failed to allocate a device address\n");
+      free(hentry);
+    }
+  else
+    {
+      /* Initialize the hash table entry */
+
+      hentry->devaddr = devaddr;
+      hentry->payload = associate;
+
+      /* Add the new device address to the hash table */
+
+      hvalue = usbhost_devaddr_hash(devaddr);
+      hentry->flink = hcd->hashtab[hvalue];
+      hcd->hashtab[hvalue] = hentry;
+
+      /* Try to re-use the lowest numbered device addresses */
+
+      if (hcd->next > devaddr)
+        {
+          hcd->next = devaddr;
+        }
+    }
+
+  usbhost_givesem(hcd);
+  return devaddr;
+}
+
+/*******************************************************************************
+ * Name: usbhost_devaddr_find
+ *
+ * Description:
+ *   Given a device address, find the void* value that was bound to the device
+ *   address by usbhost_devaddr_create() when the device address was allocated.
+ *
+ *******************************************************************************/
+
+FAR void *usbhost_devaddr_find(FAR struct usbhost_devaddr_s *hcd,
+                               uint8_t devaddr)
+{
+  FAR struct usbhost_devhash_s *hentry;
+  uint8_t hvalue;
+
+  /* Get exclusive access to the HCD device address data */
+
+  hvalue = usbhost_devaddr_hash(devaddr);
+  usbhost_takesem(hcd);
+
+  /* Check each entry in the hash table */
+
+  for (hentry = hcd->hashtab[hvalue]; hentry; hentry = hentry->flink)
+    {
+      /* Is this the address we are looking for? */
+
+      if (hentry->devaddr == devaddr)
+        {
+          /* Yes.. return the payload from the hash table entry */
+
+          usbhost_givesem(hcd);
+          return hentry->payload;
+        }
+    }
+
+  /* Didn't find the device address */
+
+  usbhost_givesem(hcd);
+  return NULL;
+}
+
+/*******************************************************************************
+ * Name: usbhost_devaddr_destroy
+ *
+ * Description:
+ *   Release a device address previously allocated by usbhost_devaddr_destroy()
+ *   and destroy the association with the void* data.
+ *
+ *******************************************************************************/
+
+void usbhost_devaddr_destroy(FAR struct usbhost_devaddr_s *hcd, uint8_t devaddr)
+{
+  FAR struct usbhost_devhash_s *hentry;
+  FAR struct usbhost_devhash_s *prev;
+  uint8_t hvalue;
+
+  /* Get exclusive access to the HCD device address data */
+
+  hvalue = usbhost_devaddr_hash(devaddr);
+  usbhost_takesem(hcd);
+
+  /* Search the hast table for the matching entry */
+
+  for (hentry = hcd->hashtab[hvalue], prev = NULL;
+       hentry;
+       prev = hentry, hentry = hentry->flink)
+    {
+      /* Is this the address we are looking for? */
+
+      if (hentry->devaddr == devaddr)
+        {
+          /* Yes.. remove the entry from the hash list */
+
+          if (prev)
+            {
+              prev->flink = hentry->flink;
+            }
+          else
+            {
+              hcd->hashtab[hvalue] = hentry->flink;
+            }
+
+          /* And release the entry */
+
+          kfree(hentry);
+          break;
+        }
+    }
+
+  usbhost_givesem(hcd);
+}
diff --git a/include/nuttx/usb/pl2303.h b/include/nuttx/usb/pl2303.h
index 4e755d10da4d52a57e5ba4e3f48b3072bf5f6b74..925010db0273ce8d351e11316ea61cb3ff6fcc31 100644
--- a/include/nuttx/usb/pl2303.h
+++ b/include/nuttx/usb/pl2303.h
@@ -81,7 +81,7 @@ extern "C"
  *
  ************************************************************************************/
 
-EXTERN int usbdev_serialinitialize(int minor);
+int usbdev_serialinitialize(int minor);
 
 #undef EXTERN
 #if defined(__cplusplus)
diff --git a/include/nuttx/usb/usbhost_devaddr.h b/include/nuttx/usb/usbhost_devaddr.h
new file mode 100644
index 0000000000000000000000000000000000000000..4945f99e3e74d8f8af53383c19d976c4d51f6698
--- /dev/null
+++ b/include/nuttx/usb/usbhost_devaddr.h
@@ -0,0 +1,150 @@
+/*******************************************************************************
+ * include/nuttx/usb/usbhost_devaddr.h
+ * Manage USB device addresses
+ *
+ *   Copyright (C) 2013 Gregory Nutt. All rights reserved.
+ *   Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * NOTE:  This interface was inspired by the Linux gadget interface by
+ * David Brownell. That work was very helpful in determining a usable
+ * partitioning of functionality between standard class drivers and various
+ * implementations of USB controller drivers.  This work, however, does
+ * not derive directly from that work and is licensed differently.
+ *
+ * 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.
+ *
+ *******************************************************************************/
+
+#ifndef _INCLUDE_NUTTX_USB_USBHOST_DEVADDR_H
+#define _INCLUDE_NUTTX_USB_USBHOST_DEVADDR_H
+
+/*******************************************************************************
+ * Included Files
+ *******************************************************************************/
+
+#include <nuttx/config.h>
+
+/*******************************************************************************
+ * Pre-processor Definitions
+ *******************************************************************************/
+/* Configuration ***************************************************************/
+
+#define USBHOST_DEVADDR_HASHSIZE 8
+#define USBHOST_DEVADDR_HASHMASK (USBHOST_DEVADDR_HASHSIZE-1)
+
+/*******************************************************************************
+ * Public Types
+ *******************************************************************************/
+
+struct usbhost_devhash_s
+{
+  FAR struct usbhost_devhash_s *flink;
+  FAR void *payload;
+  uint8_t   devaddr;
+};
+
+struct usbhost_devaddr_s
+{
+  uint8_t   next;           /* Next device address */
+  sem_t     exclsem;        /* Enforces mutulaly exlusive access */
+  uint32_t  alloctab[4];    /* Bit allocation table */
+
+  /* Hash table */
+
+  FAR struct usbhost_devhash_s *hashtab[USBHOST_DEVADDR_HASHSIZE];
+};
+
+/*******************************************************************************
+ * Public Data
+ *******************************************************************************/
+
+#undef EXTERN
+#if defined(__cplusplus)
+#  define EXTERN extern "C"
+extern "C"
+{
+#else
+#  define EXTERN extern
+#endif
+
+/*******************************************************************************
+ * Public Functions
+ *******************************************************************************/
+
+/*******************************************************************************
+ * Name: usbhost_devaddr_initialize
+ *
+ * Description:
+ *   Initialize the caller provided struct usbhost_devaddr_s instance in
+ *   preparation for the management of device addresses on behalf of an HCD.
+ *
+ *******************************************************************************/
+
+void usbhost_devaddr_initialize(FAR struct usbhost_devaddr_s *hcd);
+
+/*******************************************************************************
+ * Name: usbhost_devaddr_create
+ *
+ * Description:
+ *   Create a new unique device address for this HCD.  Bind the void* arg to the
+ *   the device address and return the newly allocated device address.
+ *
+ *******************************************************************************/
+
+int usbhost_devaddr_create(FAR struct usbhost_devaddr_s *hcd,
+                           FAR void *associate);
+
+/*******************************************************************************
+ * Name: usbhost_devaddr_find
+ *
+ * Description:
+ *   Given a device address, find the void* value that was bound to the device
+ *   address by usbhost_devaddr_create() when the device address was allocated.
+ *
+ *******************************************************************************/
+
+FAR void *usbhost_devaddr_find(FAR struct usbhost_devaddr_s *hcd,
+                               uint8_t devaddr);
+
+/*******************************************************************************
+ * Name: usbhost_devaddr_destroy
+ *
+ * Description:
+ *   Release a device address previously allocated by usbhost_devaddr_destroy()
+ *   and destroy the association with the void* data.
+ *
+ *******************************************************************************/
+
+void usbhost_devaddr_destroy(FAR struct usbhost_devaddr_s *hcd, uint8_t devaddr);
+
+#undef EXTERN
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* _INCLUDE_NUTTX_USB_USBHOST_DEVADDR_H */