summaryrefslogtreecommitdiff
path: root/nuttx/drivers/usbhost/usbhost_findclass.c
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2010-12-15 03:12:09 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2010-12-15 03:12:09 +0000
commit13c8a7486f867fa26a6e60a42e1578d29749dad7 (patch)
tree7d9124ff748344ef0bbe3af9a0f37eebddf32c18 /nuttx/drivers/usbhost/usbhost_findclass.c
parent0a03557c61b735a872b4a62604ad0b6d766d945b (diff)
downloadnuttx-13c8a7486f867fa26a6e60a42e1578d29749dad7.tar.gz
nuttx-13c8a7486f867fa26a6e60a42e1578d29749dad7.tar.bz2
nuttx-13c8a7486f867fa26a6e60a42e1578d29749dad7.zip
A little more USB host logic
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3178 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/drivers/usbhost/usbhost_findclass.c')
-rw-r--r--nuttx/drivers/usbhost/usbhost_findclass.c105
1 files changed, 103 insertions, 2 deletions
diff --git a/nuttx/drivers/usbhost/usbhost_findclass.c b/nuttx/drivers/usbhost/usbhost_findclass.c
index 3085b7ffd..8d829defe 100644
--- a/nuttx/drivers/usbhost/usbhost_findclass.c
+++ b/nuttx/drivers/usbhost/usbhost_findclass.c
@@ -38,8 +38,21 @@
****************************************************************************/
#include <nuttx/config.h>
+#include <stdbool.h>
+#include <nuttx/usb/usb.h>
#include <nuttx/usb/usbhost.h>
+#include <arch/irq.h>
+
+#include "usbhost_registry.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
/****************************************************************************
* Private Function Prototypes
@@ -54,6 +67,58 @@
****************************************************************************/
/****************************************************************************
+ * Name: usbhost_idmatch
+ *
+ * Description:
+ * Check if the class ID matches what the host controller found.
+ *
+ * Input Parameters:
+ * classid - ID info for the class under consideration.
+ * devid - ID info reported by the device.
+ *
+ * Returned Values:
+ * TRUE - the class will support this device.
+ *
+ ****************************************************************************/
+
+static bool usbhost_ismatch(const struct usbhost_id_s *classid,
+ const struct usbhost_id_s *devid)
+{
+ /* The base class ID, subclass and protocol have to match up in any event */
+
+ if (devid->base == classid->base &&
+ devid->subclass == classid->subclass &&
+ devid->proto == clsssid->proto)
+ {
+ /* If this is a vendor-specific class ID, then the VID and PID have to
+ * match as well.
+ */
+
+ if (devid->base == USB_CLASS_VENDOR_SPEC)
+ {
+ /* Vendor specific... do the VID and PID also match? */
+
+ if (devid->vid == classid->vid && devid->pid == classid->pid)
+ {
+ /* Yes.. then we have a match */
+
+ return true;
+ }
+ }
+ else
+ {
+ /* Not vendor specific? Then we have a match */
+
+ return true;
+ }
+ }
+
+ /* No match.. not supported */
+
+ return false;
+}
+
+/****************************************************************************
* Public Functions
****************************************************************************/
@@ -80,7 +145,43 @@
const struct usbhost_registry_s *usbhost_findclass(const struct usbhost_id_s *id)
{
-#warning "Not Implemented"
- return NULL;
+ struct usbhost_registry_s *class;
+ irqstate_t flags;
+ int ndx;
+
+ /* g_classregistry is a singly-linkedlist of class ID information added by
+ * calls to usbhost_registerclass(). Since this list is accessed from USB
+ * host controller interrupt handling logic, accesses to this list must be
+ * protected by disabling interrupts.
+ */
+
+ flags = irqsave();
+
+ /* Examine each register class in the linked list */
+
+ for (class = g_classregistry; class; class = class->flink)
+ {
+ /* If the registered class supports more than one ID, subclass, or
+ * protocol, then try each.
+ */
+
+ for (ndx = 0; ndx < class->nids; ndx++)
+ {
+ /* Did we find a matching ID? */
+
+ if (usbhost_idmatch(&class->id[ndx], id))
+ {
+ /* Yes.. restore interrupts and return the class info */
+
+ irqrestore(flags);
+ return class;
+ }
+ }
+ }
+
+ /* Not found... restore interrupts and return NULL */
+
+ irqrestore(flags);
+ return NULL;
}