<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>