<p>laforge <strong>submitted</strong> this change.</p><p><a href="https://gerrit.osmocom.org/c/osmo-e1d/+/21800">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  Jenkins Builder: Verified
  laforge: Looks good to me, approved
  tnt: Looks good to me, but someone else must approve

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">support for control endpoint requests to icE1usb to switch Rx/Tx mode<br><br>Change-Id: I62f3175a216eb5db0847f4b16c91bc23697a7623<br>---<br>M src/usb.c<br>1 file changed, 108 insertions(+), 0 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/usb.c b/src/usb.c</span><br><span>index fcd4000..c40a7af 100644</span><br><span>--- a/src/usb.c</span><br><span>+++ b/src/usb.c</span><br><span>@@ -77,6 +77,9 @@</span><br><span>     /* Rate regulation */</span><br><span>        uint32_t r_acc;</span><br><span>      uint32_t r_sw;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      /* list of in-progress CTRL operations */</span><br><span style="color: hsl(120, 100%, 40%);">+     struct llist_head ctrl_inprogress;</span><br><span> };</span><br><span> </span><br><span> struct e1_usb_intf_data {</span><br><span>@@ -377,6 +380,110 @@</span><br><span> }</span><br><span> </span><br><span> // ---------------------------------------------------------------------------</span><br><span style="color: hsl(120, 100%, 40%);">+// Control transfers</span><br><span style="color: hsl(120, 100%, 40%);">+// ---------------------------------------------------------------------------</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct e1_usb_ctrl_xfer {</span><br><span style="color: hsl(120, 100%, 40%);">+       struct e1_line *line;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct llist_head list;</span><br><span style="color: hsl(120, 100%, 40%);">+       /* 8 bytes control setup packet, remainder for data */</span><br><span style="color: hsl(120, 100%, 40%);">+        uint8_t buffer[8 + 8];</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void</span><br><span style="color: hsl(120, 100%, 40%);">+ctrl_xfer_compl_cb(struct libusb_transfer *xfr)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       struct e1_usb_ctrl_xfer *ucx = xfr->user_data;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   switch (xfr->status) {</span><br><span style="color: hsl(120, 100%, 40%);">+     case LIBUSB_TRANSFER_COMPLETED:</span><br><span style="color: hsl(120, 100%, 40%);">+               LOGPLI(ucx->line, DE1D, LOGL_INFO, "CTRL transfer completed successfully\n");</span><br><span style="color: hsl(120, 100%, 40%);">+            break;</span><br><span style="color: hsl(120, 100%, 40%);">+        default:</span><br><span style="color: hsl(120, 100%, 40%);">+              LOGPLI(ucx->line, DE1D, LOGL_ERROR, "CTRL transfer completed unsuccessfully %d\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                       xfr->status);</span><br><span style="color: hsl(120, 100%, 40%);">+              break;</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+     llist_del(&ucx->list);</span><br><span style="color: hsl(120, 100%, 40%);">+ talloc_free(ucx);</span><br><span style="color: hsl(120, 100%, 40%);">+     libusb_free_transfer(xfr);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* generic helper for async transmission of control endpoint requests */</span><br><span style="color: hsl(120, 100%, 40%);">+static int</span><br><span style="color: hsl(120, 100%, 40%);">+_e1_usb_line_send_ctrl(struct e1_line *line, uint8_t bmReqType, uint8_t bReq, uint16_t wValue,</span><br><span style="color: hsl(120, 100%, 40%);">+                const uint8_t *data, size_t data_len)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       struct e1_usb_ctrl_xfer *ucx = talloc_zero(line, struct e1_usb_ctrl_xfer);</span><br><span style="color: hsl(120, 100%, 40%);">+    struct e1_usb_line_data *ld = (struct e1_usb_line_data *) line->drv_data;</span><br><span style="color: hsl(120, 100%, 40%);">+  struct e1_usb_intf_data *id = (struct e1_usb_intf_data *) line->intf->drv_data;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct libusb_transfer *xfr;</span><br><span style="color: hsl(120, 100%, 40%);">+  int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     if (!ucx)</span><br><span style="color: hsl(120, 100%, 40%);">+             return -ENOMEM;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     OSMO_ASSERT(sizeof(ucx->buffer) >= 8+data_len);</span><br><span style="color: hsl(120, 100%, 40%);">+ ucx->line = line;</span><br><span style="color: hsl(120, 100%, 40%);">+  libusb_fill_control_setup(ucx->buffer, bmReqType, bReq, wValue, ld->if_num, data_len);</span><br><span style="color: hsl(120, 100%, 40%);">+  if (data && data_len)</span><br><span style="color: hsl(120, 100%, 40%);">+         memcpy(ucx->buffer+8, data, data_len);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   xfr = libusb_alloc_transfer(0);</span><br><span style="color: hsl(120, 100%, 40%);">+       if (!xfr) {</span><br><span style="color: hsl(120, 100%, 40%);">+           rc = -ENOMEM;</span><br><span style="color: hsl(120, 100%, 40%);">+         goto free_ucx;</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   libusb_fill_control_transfer(xfr, id->devh, ucx->buffer, ctrl_xfer_compl_cb, ucx, 3000);</span><br><span style="color: hsl(120, 100%, 40%);">+        rc = libusb_submit_transfer(xfr);</span><br><span style="color: hsl(120, 100%, 40%);">+     if (rc != 0)</span><br><span style="color: hsl(120, 100%, 40%);">+          goto free_xfr;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      llist_add_tail(&ucx->list, &ld->ctrl_inprogress);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+free_xfr:</span><br><span style="color: hsl(120, 100%, 40%);">+        libusb_free_transfer(xfr);</span><br><span style="color: hsl(120, 100%, 40%);">+free_ucx:</span><br><span style="color: hsl(120, 100%, 40%);">+ talloc_free(ucx);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return rc;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int</span><br><span style="color: hsl(120, 100%, 40%);">+e1_usb_ctrl_set_tx_cfg(struct e1_line *line, enum ice1usb_tx_mode mode, enum ice1usb_tx_timing timing,</span><br><span style="color: hsl(120, 100%, 40%);">+                  enum ice1usb_tx_ext_loopback ext_loop, uint8_t alarm)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      const uint16_t bmReqType = LIBUSB_RECIPIENT_INTERFACE | LIBUSB_REQUEST_TYPE_VENDOR |</span><br><span style="color: hsl(120, 100%, 40%);">+                             LIBUSB_ENDPOINT_OUT;</span><br><span style="color: hsl(120, 100%, 40%);">+       struct ice1usb_tx_config tx_cfg = {</span><br><span style="color: hsl(120, 100%, 40%);">+           .mode = mode,</span><br><span style="color: hsl(120, 100%, 40%);">+         .timing = timing,</span><br><span style="color: hsl(120, 100%, 40%);">+             .ext_loopback = ext_loop,</span><br><span style="color: hsl(120, 100%, 40%);">+             .alarm = alarm,</span><br><span style="color: hsl(120, 100%, 40%);">+       };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  return _e1_usb_line_send_ctrl(line, bmReqType, ICE1USB_INTF_SET_TX_CFG, 0, (uint8_t *)&tx_cfg,</span><br><span style="color: hsl(120, 100%, 40%);">+                                  sizeof(tx_cfg));</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int</span><br><span style="color: hsl(120, 100%, 40%);">+e1_usb_ctrl_set_rx_cfg(struct e1_line *line, enum ice1usb_rx_mode mode)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  const uint16_t bmReqType = LIBUSB_RECIPIENT_INTERFACE | LIBUSB_REQUEST_TYPE_VENDOR |</span><br><span style="color: hsl(120, 100%, 40%);">+                             LIBUSB_ENDPOINT_OUT;</span><br><span style="color: hsl(120, 100%, 40%);">+       struct ice1usb_rx_config rx_cfg = {</span><br><span style="color: hsl(120, 100%, 40%);">+           .mode = mode,</span><br><span style="color: hsl(120, 100%, 40%);">+ };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  return _e1_usb_line_send_ctrl(line, bmReqType, ICE1USB_INTF_SET_RX_CFG, 0, (uint8_t *)&rx_cfg,</span><br><span style="color: hsl(120, 100%, 40%);">+                                  sizeof(rx_cfg));</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+// ---------------------------------------------------------------------------</span><br><span> // Init / Probing</span><br><span> // ---------------------------------------------------------------------------</span><br><span> </span><br><span>@@ -435,6 +542,7 @@</span><br><span>                 /* Setup driver data and find endpoints */</span><br><span>           line_data = talloc_zero(e1d->ctx, struct e1_usb_line_data);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+            INIT_LLIST_HEAD(&line_data->ctrl_inprogress);</span><br><span>                 line_data->if_num = id->bInterfaceNumber;</span><br><span>              line_data->r_acc  = 0;</span><br><span>            line_data->r_sw   = 8192;</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmo-e1d/+/21800">change 21800</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/c/osmo-e1d/+/21800"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: osmo-e1d </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: I62f3175a216eb5db0847f4b16c91bc23697a7623 </div>
<div style="display:none"> Gerrit-Change-Number: 21800 </div>
<div style="display:none"> Gerrit-PatchSet: 5 </div>
<div style="display:none"> Gerrit-Owner: laforge <laforge@osmocom.org> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder </div>
<div style="display:none"> Gerrit-Reviewer: laforge <laforge@osmocom.org> </div>
<div style="display:none"> Gerrit-Reviewer: tnt <tnt@246tNt.com> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>