Fishwaldo commented on code in PR #19745:
URL: https://github.com/apache/nuttx/pull/19745#discussion_r3788722815
##########
drivers/usbhost/usbhost_xhci.c:
##########
@@ -5157,11 +5208,186 @@ static int xhci_cancel(FAR struct usbhost_driver_s
*drvr, usbhost_ep_t ep)
****************************************************************************/
#ifdef CONFIG_USBHOST_HUB
+/****************************************************************************
+ * Name: xhci_rhport_from_hport
+ *
+ * Description:
+ * The root hub port a device descends from, however many hubs are in the
+ * way. The slot context names it, because that is the port the traffic
+ * physically leaves by.
+ *
+ ****************************************************************************/
+
+static FAR struct xhci_rhport_s *
+xhci_rhport_from_hport(FAR struct usbhost_xhci_s *priv,
+ FAR struct usbhost_hubport_s *hport)
+{
+ while (hport->parent != NULL)
+ {
+ hport = hport->parent;
+ }
+
+ return &priv->rhport[hport->port];
+}
+
+/****************************************************************************
+ * Name: xhci_hub_update
+ *
+ * Description:
+ * Tell the controller that a device is a hub, so that it will route to
+ * what is behind it.
+ *
+ * The slot was created before anyone knew: a hub is addressed and
+ * configured like any other device, and only then does its class driver
+ * read the descriptor saying how many ports it has. So the slot context
+ * is corrected here, the first time something appears behind it.
+ *
+ ****************************************************************************/
+
+static int xhci_hub_update(FAR struct usbhost_xhci_s *priv,
+ FAR struct usbhost_hubport_s *hubport)
+{
+ FAR struct xhci_slot_ctx_s *in;
+ FAR struct xhci_dev_s *dev;
+ uint64_t ctx;
+ int ret;
+
+ dev = xhci_dev_from_hport(priv, hubport);
+ if (dev == NULL || dev->ishub || hubport->nports == 0)
+ {
+ /* Nothing to correct: no slot for it, already done, or the hub class
+ * driver has not reported the descriptor.
+ */
+
+ return OK;
+ }
+
+ ret = nxmutex_lock(&priv->lock);
+ if (ret < 0)
+ {
+ return ret;
+ }
+
+ /* Only the slot context changes, and it must go in carrying everything
+ * the controller already holds, so start from the output context it has
+ * been maintaining.
+ */
+
+ up_invalidate_dcache((uintptr_t)dev->ctx,
+ (uintptr_t)dev->ctx + XHCI_DEVCTX_SIZE(priv));
+
+ xhci_context_ctrl(priv, dev, 0, XHCI_IN_CTX1_A(XHCI_SLOT_FLAG));
+
+ in = xhci_in_slot(priv, dev->input);
+ in->ctx[0] = xhci_out_slot(dev->ctx)->ctx[0] | htole32(XHCI_ST_CTX0_HUB);
+ in->ctx[1] = (xhci_out_slot(dev->ctx)->ctx[1] &
+ ~htole32(XHCI_ST_CTX1_PORTS_MASK)) |
+ htole32(XHCI_ST_CTX1_PORTS_SET(hubport->nports));
+ in->ctx[2] = (xhci_out_slot(dev->ctx)->ctx[2] &
+ ~htole32(XHCI_ST_CTX2_TTT_MASK)) |
+ htole32(XHCI_ST_CTX2_TTT_SET(hubport->ttt));
+ in->ctx[3] = xhci_out_slot(dev->ctx)->ctx[3];
+
+ up_flush_dcache((uintptr_t)dev->input,
+ (uintptr_t)dev->input + XHCI_INCTX_SIZE(priv));
+
+ ctx = up_addrenv_va_to_pa(dev->input);
+
+ nxmutex_unlock(&priv->lock);
+
+ ret = xhci_cmd_cfgep(priv, dev->slot, ctx, false);
+ if (ret < 0)
+ {
+ uerr("failed to describe the hub on slot %d: %d\n", dev->slot, ret);
+ return ret;
+ }
+
+ dev->ishub = true;
+
+ syslog(LOG_INFO, "%s: port %d: hub with %d port%s\n",
Review Comment:
Fixed.
There were 3 other syslog uses in this file. Two at INFO level for connect
and disconnect of devices and one at WARN level for enumeration. I left them at
syslog as I genuinely think they are valuable. Let me know if you think
otherwise.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]