func: static int xhci_fire_ctl_transfer(XHCIState *xhci, XHCITransfer *xfer)
  
  {
  
      XHCITRB *trb_setup, *trb_status;
  
      uint8_t bmRequestType;
  
  
  
      trb_setup = &xfer->trbs[0];
  
      trb_status = &xfer->trbs[xfer->trb_count-1];
  
  
  
      trace_usb_xhci_xfer_start(xfer, xfer->epctx->slotid,
  
                                xfer->epctx->epid, xfer->streamid);
  
  
  
      /* at most one Event Data TRB allowed after STATUS */
  
      if (TRB_TYPE(*trb_status) == TR_EVDATA && xfer->trb_count > 2) {
  
          trb_status--;
  
      }
  
  
  
      /* do some sanity checks */
  
      if (TRB_TYPE(*trb_setup) != TR_SETUP) {
  
          DPRINTF("xhci: ep0 first TD not SETUP: %d\n",
  
                  TRB_TYPE(*trb_setup));
  
          return -1;
  
      }
  
      if (TRB_TYPE(*trb_status) != TR_STATUS) {
  
          DPRINTF("xhci: ep0 last TD not STATUS: %d\n",
  
                  TRB_TYPE(*trb_status));
  
          return -1;
  
      }
  
      if (!(trb_setup->control & TRB_TR_IDT)) {
  
          DPRINTF("xhci: Setup TRB doesn't have IDT set\n");
  
          return -1;
  
      }
  
      if ((trb_setup->status & 0x1ffff) != 8) {
  
          DPRINTF("xhci: Setup TRB has bad length (%d)\n",
  
                  (trb_setup->status & 0x1ffff));
  
          return -1;
  
      }
  
  
  
      bmRequestType = trb_setup->parameter;
  
  
  
      xfer->in_xfer = bmRequestType & USB_DIR_IN;
  
      xfer->iso_xfer = false;
  
      xfer->timed_xfer = false;
  
  
  
      if (xhci_setup_packet(xfer) < 0) {
  
          return -1;
  
      }
  
      xfer->packet.parameter = trb_setup->parameter;
  
  
  
      usb_handle_packet(xfer->packet.ep->dev, &xfer->packet);
  
  
  
      xhci_try_complete_packet(xfer);
  
      if (!xfer->running_async && !xfer->running_retry) {
  
          xhci_kick_epctx(xfer->epctx, 0);
  
      }
  
      return 0;
  
  }
  