void stm32_usbinitialize(void) { ulldbg("called\n"); /* USB Soft Connect Pullup */ stm32_configgpio(GPIO_USB_PULLUP); }
void stm32_usbsuspend(FAR struct usbdev_s *dev, bool resume) { ulldbg("resume: %d\n", resume); }
static inline int usbhost_cfgdesc(FAR struct usbhost_class_s *hubclass, FAR const uint8_t *configdesc, int desclen) { FAR struct usbhost_hubpriv_s *priv; FAR struct usbhost_hubport_s *hport; FAR struct usb_cfgdesc_s *cfgdesc; FAR struct usb_desc_s *desc; FAR struct usbhost_epdesc_s intindesc; int remaining; uint8_t found = 0; int ret; DEBUGASSERT(hubclass != NULL); priv = &((FAR struct usbhost_hubclass_s *)hubclass)->hubpriv; DEBUGASSERT(hubclass->hport); hport = hubclass->hport; DEBUGASSERT(configdesc != NULL && desclen >= sizeof(struct usb_cfgdesc_s)); /* Initialize the interrupt IN endpoint information (only to prevent * compiler complaints) */ intindesc.hport = hport; intindesc.addr = 0; intindesc.in = true; intindesc.xfrtype = USB_EP_ATTR_XFER_INT; intindesc.interval = 0; intindesc.mxpacketsize = 0; /* Verify that we were passed a configuration descriptor */ cfgdesc = (FAR struct usb_cfgdesc_s *)configdesc; if (cfgdesc->type != USB_DESC_TYPE_CONFIG) { return -EINVAL; } /* Get the total length of the configuration descriptor (little endian). * It might be a good check to get the number of interfaces here too. */ remaining = (int)usbhost_getle16(cfgdesc->totallen); /* Skip to the next entry descriptor */ configdesc += cfgdesc->len; remaining -= cfgdesc->len; /* Loop where there are more descriptors to examine */ while (remaining >= sizeof(struct usb_desc_s)) { /* What is the next descriptor? */ desc = (FAR struct usb_desc_s *)configdesc; switch (desc->type) { /* Interface descriptor. We really should get the number of endpoints * from this descriptor too. */ case USB_DESC_TYPE_INTERFACE: { FAR struct usb_ifdesc_s *ifdesc = (FAR struct usb_ifdesc_s *)configdesc; uvdbg("Interface descriptor\n"); DEBUGASSERT(remaining >= USB_SIZEOF_IFDESC); /* Save the interface number and mark ONLY the interface found */ priv->ifno = ifdesc->ifno; found = USBHOST_IFFOUND; } break; /* Endpoint descriptor. Here, we expect one interrupt IN endpoints. */ case USB_DESC_TYPE_ENDPOINT: { FAR struct usb_epdesc_s *epdesc = (FAR struct usb_epdesc_s *)configdesc; uvdbg("Endpoint descriptor\n"); DEBUGASSERT(remaining >= USB_SIZEOF_EPDESC); /* Check for an interrupt endpoint. */ if ((epdesc->attr & USB_EP_ATTR_XFERTYPE_MASK) == USB_EP_ATTR_XFER_INT) { /* Yes.. it is a interrupt endpoint. IN or OUT? */ if (USB_ISEPOUT(epdesc->addr)) { /* It is an OUT interrupt endpoint. Ignore */ uvdbg("Interrupt OUT EP addr:%d mxpacketsize:%d\n", (epdesc->addr & USB_EP_ADDR_NUMBER_MASK), usbhost_getle16(epdesc->mxpacketsize)); } else { /* It is an IN interrupt endpoint. */ found |= USBHOST_EPINFOUND; /* Save the interrupt IN endpoint information */ intindesc.addr = epdesc->addr & USB_EP_ADDR_NUMBER_MASK; intindesc.interval = epdesc->interval; intindesc.mxpacketsize = usbhost_getle16(epdesc->mxpacketsize); uvdbg("Interrupt IN EP: addr=%d interval=%d mxpacketsize=%d\n", intindesc.addr, intindesc.interval, intindesc.mxpacketsize); } } } break; /* Other descriptors are just ignored for now */ default: break; } /* If we found everything we need with this interface, then break out * of the loop early. */ if (found == USBHOST_ALLFOUND) { break; } /* Increment the address of the next descriptor */ configdesc += desc->len; remaining -= desc->len; } /* Sanity checking... did we find all of things that we need? */ if (found != USBHOST_ALLFOUND) { ulldbg("ERROR: Found IF=%s EPIN=%s\n", (found & USBHOST_IFFOUND) != 0 ? "YES" : "NO", (found & USBHOST_EPINFOUND) != 0 ? "YES" : "NO"); return -EINVAL; } /* We are good... Allocate the interrupt IN endpoint */ ret = DRVR_EPALLOC(hport->drvr, &intindesc, &priv->intin); if (ret < 0) { udbg("ERROR: Failed to allocate Interrupt IN endpoint: %d\n", ret); (void)DRVR_EPFREE(hport->drvr, priv->intin); return ret; } ullvdbg("Endpoint allocated\n"); return OK; }
static void usbhost_callback(FAR void *arg, ssize_t nbytes) { FAR struct usbhost_class_s *hubclass; FAR struct usbhost_hubpriv_s *priv; uint32_t delay = 0; DEBUGASSERT(arg != NULL); hubclass = (FAR struct usbhost_class_s *)arg; priv = &((FAR struct usbhost_hubclass_s *)hubclass)->hubpriv; /* Check for a failure. On higher end host controllers, the asynchronous * transfer will pend until data is available (OHCI and EHCI). On lower * end host controllers (like STM32 and EFM32), the transfer will fail * immediately when the device NAKs the first attempted interrupt IN * transfer (with nbytes == -EAGAIN). In that case (or in the case of * other errors), we must fall back to polling. */ if (nbytes < 0) { /* This debug output is good to know, but really a nuisance for * those configurations where we have to fall back to polling. * FIX: Don't output the message is the result is -EAGAIN. */ #if defined(CONFIG_DEBUG_USB) && !defined(CONFIG_DEBUG_VERBOSE) if (nbytes != -EAGAIN) #endif { ulldbg("ERROR: Transfer failed: %d\n", (int)nbytes); } /* Indicate there there is nothing to do. So when the work is * performed, nothing will happen other than we will set to receive * the next event. */ priv->buffer[0] = 0; /* We don't know the nature of the failure, but we need to do all that * we can do to avoid a CPU hog error loop. * * Use the low-priority work queue and delay polling for the next * event. We want to use as little CPU bandwidth as possible in this * case. */ delay = POLL_DELAY; } /* The work structure should always be available since hub communications * are serialized. However, there is a remote chance that this may * collide with a hub disconnection event. */ if (work_available(&priv->work) && !priv->disconnected) { (void)work_queue(LPWORK, &priv->work, (worker_t)usbhost_hub_event, hubclass, delay); } }
void sam_udp_suspend(FAR struct usbdev_s *dev, bool resume) { ulldbg("resume: %d\n", resume); }
void kinetis_usbsuspend(FAR struct usbdev_s *dev, bool resume) { ulldbg("resume: %d\n", resume); #warning "Missing logic" }
static inline int usbhost_cfgdesc(FAR struct usbhost_state_s *priv, FAR const uint8_t *configdesc, int desclen) { FAR struct usbhost_hubport_s *hport; FAR struct usb_cfgdesc_s *cfgdesc; FAR struct usb_desc_s *desc; FAR struct usbhost_epdesc_s bindesc; FAR struct usbhost_epdesc_s boutdesc; int remaining; uint8_t found = 0; int ret; DEBUGASSERT(priv != NULL && priv->usbclass.hport && configdesc != NULL && desclen >= sizeof(struct usb_cfgdesc_s)); hport = priv->usbclass.hport; /* Verify that we were passed a configuration descriptor */ cfgdesc = (FAR struct usb_cfgdesc_s *)configdesc; if (cfgdesc->type != USB_DESC_TYPE_CONFIG) { return -EINVAL; } /* Get the total length of the configuration descriptor (little endian). * It might be a good check to get the number of interfaces here too. */ remaining = (int)usbhost_getle16(cfgdesc->totallen); /* Skip to the next entry descriptor */ configdesc += cfgdesc->len; remaining -= cfgdesc->len; /* Loop where there are more dscriptors to examine */ while (remaining >= sizeof(struct usb_desc_s)) { /* What is the next descriptor? */ desc = (FAR struct usb_desc_s *)configdesc; switch (desc->type) { /* Interface descriptor. We really should get the number of endpoints * from this descriptor too. */ case USB_DESC_TYPE_INTERFACE: { FAR struct usb_ifdesc_s *ifdesc = (FAR struct usb_ifdesc_s *)configdesc; uvdbg("Interface descriptor\n"); DEBUGASSERT(remaining >= USB_SIZEOF_IFDESC); /* Save the interface number and mark ONLY the interface found */ priv->ifno = ifdesc->ifno; found = USBHOST_IFFOUND; } break; /* Endpoint descriptor. Here, we expect two bulk endpoints, an IN * and an OUT. */ case USB_DESC_TYPE_ENDPOINT: { FAR struct usb_epdesc_s *epdesc = (FAR struct usb_epdesc_s *)configdesc; uvdbg("Endpoint descriptor\n"); DEBUGASSERT(remaining >= USB_SIZEOF_EPDESC); /* Check for a bulk endpoint. */ if ((epdesc->attr & USB_EP_ATTR_XFERTYPE_MASK) == USB_EP_ATTR_XFER_BULK) { /* Yes.. it is a bulk endpoint. IN or OUT? */ if (USB_ISEPOUT(epdesc->addr)) { /* It is an OUT bulk endpoint. There should be only one * bulk OUT endpoint. */ if ((found & USBHOST_BOUTFOUND) != 0) { /* Oops.. more than one endpoint. We don't know * what to do with this. */ return -EINVAL; } found |= USBHOST_BOUTFOUND; /* Save the bulk OUT endpoint information */ boutdesc.hport = hport; boutdesc.addr = epdesc->addr & USB_EP_ADDR_NUMBER_MASK; boutdesc.in = false; boutdesc.xfrtype = USB_EP_ATTR_XFER_BULK; boutdesc.interval = epdesc->interval; boutdesc.mxpacketsize = usbhost_getle16(epdesc->mxpacketsize); uvdbg("Bulk OUT EP addr:%d mxpacketsize:%d\n", boutdesc.addr, boutdesc.mxpacketsize); } else { /* It is an IN bulk endpoint. There should be only one * bulk IN endpoint. */ if ((found & USBHOST_BINFOUND) != 0) { /* Oops.. more than one endpoint. We don't know * what to do with this. */ return -EINVAL; } found |= USBHOST_BINFOUND; /* Save the bulk IN endpoint information */ bindesc.hport = hport; bindesc.addr = epdesc->addr & USB_EP_ADDR_NUMBER_MASK; bindesc.in = 1; bindesc.xfrtype = USB_EP_ATTR_XFER_BULK; bindesc.interval = epdesc->interval; bindesc.mxpacketsize = usbhost_getle16(epdesc->mxpacketsize); uvdbg("Bulk IN EP addr:%d mxpacketsize:%d\n", bindesc.addr, bindesc.mxpacketsize); } } } break; /* Other descriptors are just ignored for now */ default: break; } /* If we found everything we need with this interface, then break out * of the loop early. */ if (found == USBHOST_ALLFOUND) { break; } /* Increment the address of the next descriptor */ configdesc += desc->len; remaining -= desc->len; } /* Sanity checking... did we find all of things that we need? */ if (found != USBHOST_ALLFOUND) { ulldbg("ERROR: Found IF:%s BIN:%s BOUT:%s\n", (found & USBHOST_IFFOUND) != 0 ? "YES" : "NO", (found & USBHOST_BINFOUND) != 0 ? "YES" : "NO", (found & USBHOST_BOUTFOUND) != 0 ? "YES" : "NO"); return -EINVAL; } /* We are good... Allocate the endpoints */ ret = DRVR_EPALLOC(hport->drvr, &boutdesc, &priv->epout); if (ret < 0) { udbg("ERROR: Failed to allocate Bulk OUT endpoint\n"); return ret; } ret = DRVR_EPALLOC(hport->drvr, &bindesc, &priv->epin); if (ret < 0) { udbg("ERROR: Failed to allocate Bulk IN endpoint\n"); (void)DRVR_EPFREE(hport->drvr, priv->epout); return ret; } ullvdbg("Endpoints allocated\n"); return OK; }