static int usb_send_cmd_packet(uint8_t *packet, int size){
    int r;

    if (libusb_state != LIB_USB_TRANSFERS_ALLOCATED) return -1;

    // async
    libusb_fill_control_setup(hci_cmd_buffer, LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE, 0, 0, 0, size);
    memcpy(hci_cmd_buffer + LIBUSB_CONTROL_SETUP_SIZE, packet, size);

    // prepare transfer
    int completed = 0;
    libusb_fill_control_transfer(command_out_transfer, handle, hci_cmd_buffer, async_callback, &completed, 0);
    command_out_transfer->flags = LIBUSB_TRANSFER_FREE_BUFFER;

    // update stata before submitting transfer
    usb_command_active = 1;

    // submit transfer
    r = libusb_submit_transfer(command_out_transfer);
    
    if (r < 0) {
        usb_command_active = 0;
        log_error("Error submitting cmd transfer %d", r);
        return -1;
    }

    return 0;
}
Example #2
0
static void sm_write_reg(struct fpi_ssm *ssm, unsigned char reg,
	unsigned char value)
{
	struct fp_img_dev *dev = ssm->priv;
	struct libusb_transfer *transfer = libusb_alloc_transfer(0);
	unsigned char *data;
	int r;
	
	if (!transfer) {
		fpi_ssm_mark_aborted(ssm, -ENOMEM);
		return;
	}

	fp_dbg("set %02x=%02x", reg, value);
	data = g_malloc(LIBUSB_CONTROL_SETUP_SIZE);
	libusb_fill_control_setup(data, CTRL_OUT, reg, value, 0, 0);
	libusb_fill_control_transfer(transfer, dev->udev, data, sm_write_reg_cb,
		ssm, CTRL_TIMEOUT);
	r = libusb_submit_transfer(transfer);
	if (r < 0) {
		g_free(data);
		libusb_free_transfer(transfer);
		fpi_ssm_mark_aborted(ssm, r);
	}
}
Example #3
0
static void sm_exec_cmd(struct fpi_ssm *ssm, unsigned char cmd,
	unsigned char param)
{
	struct fp_img_dev *dev = ssm->priv;
	struct libusb_transfer *transfer = libusb_alloc_transfer(0);
	unsigned char *data;
	int r;
	
	if (!transfer) {
		fpi_ssm_mark_aborted(ssm, -ENOMEM);
		return;
	}

	fp_dbg("cmd %02x param %02x", cmd, param);
	data = g_malloc(LIBUSB_CONTROL_SETUP_SIZE);
	libusb_fill_control_setup(data, CTRL_IN, cmd, param, 0, 0);
	libusb_fill_control_transfer(transfer, dev->udev, data, sm_exec_cmd_cb,
		ssm, CTRL_TIMEOUT);
	r = libusb_submit_transfer(transfer);
	if (r < 0) {
		g_free(data);
		libusb_free_transfer(transfer);
		fpi_ssm_mark_aborted(ssm, r);
	}
}
Example #4
0
void
cp_usb_async_read(struct cp_usb_async *cp, uint8_t *valuep)
{
	int	p;
	int	ret;

	if (cp->p == MAX_OUTSTANDING)
		cp_usb_async_sync(cp);
	p = cp->p;
	if (!cp->packet[p].transfer)
		cp->packet[p].transfer = libusb_alloc_transfer(0);
	cp->packet[p].valuep = valuep;
	cp->packet[p].direction = packet_read;
	libusb_fill_control_setup(cp->packet[p].data,
				  0xc0,			/* request */
				  0xff,			/* request type */
				  0x00c2,		/* value */
				  0,			/* index */
				  1);			/* length */

	libusb_fill_control_transfer(cp->packet[p].transfer,
				     cp->handle,
				     cp->packet[p].data,
				     cp_usb_async_transfer_callback,
				     cp,
				     CP_TIMEOUT);
	ccdbg_debug(CC_DEBUG_USB_ASYNC, "Read packet %d\n", p);
	ret = libusb_submit_transfer(cp->packet[p].transfer);
	if (ret)
		fprintf(stderr, "libusb_submit_transfer failed %d\n", ret);
	cp->p++;
}
Example #5
0
int LibusbDevice::SubmitTransfer(std::unique_ptr<CtrlMessage> cmd)
{
  if (!m_device_attached)
    return LIBUSB_ERROR_NOT_FOUND;

  DEBUG_LOG(IOS_USB,
            "[%04x:%04x %d] Control: bRequestType=%02x bRequest=%02x wValue=%04x"
            " wIndex=%04x wLength=%04x",
            m_vid, m_pid, m_active_interface, cmd->request_type, cmd->request, cmd->value,
            cmd->index, cmd->length);

  switch ((cmd->request_type << 8) | cmd->request)
  {
  // The following requests have to go through libusb and cannot be directly sent to the device.
  case USBHDR(DIR_HOST2DEVICE, TYPE_STANDARD, REC_INTERFACE, REQUEST_SET_INTERFACE):
  {
    INFO_LOG(IOS_USB, "[%04x:%04x %d] REQUEST_SET_INTERFACE index=%04x value=%04x", m_vid, m_pid,
             m_active_interface, cmd->index, cmd->value);
    if (static_cast<u8>(cmd->index) != m_active_interface)
    {
      const int ret = ChangeInterface(static_cast<u8>(cmd->index));
      if (ret < 0)
      {
        ERROR_LOG(IOS_USB, "[%04x:%04x %d] Failed to change interface to %d: %s", m_vid, m_pid,
                  m_active_interface, cmd->index, libusb_error_name(ret));
        return ret;
      }
    }
    const int ret = SetAltSetting(static_cast<u8>(cmd->value));
    if (ret == 0)
      m_ios.EnqueueIPCReply(cmd->ios_request, cmd->length);
    return ret;
  }
  case USBHDR(DIR_HOST2DEVICE, TYPE_STANDARD, REC_DEVICE, REQUEST_SET_CONFIGURATION):
  {
    INFO_LOG(IOS_USB, "[%04x:%04x %d] REQUEST_SET_CONFIGURATION index=%04x value=%04x", m_vid,
             m_pid, m_active_interface, cmd->index, cmd->value);
    ReleaseAllInterfacesForCurrentConfig();
    const int ret = libusb_set_configuration(m_handle, cmd->value);
    if (ret == 0)
    {
      ClaimAllInterfaces(cmd->value);
      m_ios.EnqueueIPCReply(cmd->ios_request, cmd->length);
    }
    return ret;
  }
  }

  const size_t size = cmd->length + LIBUSB_CONTROL_SETUP_SIZE;
  auto buffer = std::make_unique<u8[]>(size);
  libusb_fill_control_setup(buffer.get(), cmd->request_type, cmd->request, cmd->value, cmd->index,
                            cmd->length);
  Memory::CopyFromEmu(buffer.get() + LIBUSB_CONTROL_SETUP_SIZE, cmd->data_address, cmd->length);
  libusb_transfer* transfer = libusb_alloc_transfer(0);
  transfer->flags |= LIBUSB_TRANSFER_FREE_TRANSFER;
  libusb_fill_control_transfer(transfer, m_handle, buffer.release(), CtrlTransferCallback, this, 0);
  m_transfer_endpoints[0].AddTransfer(std::move(cmd), transfer);
  return libusb_submit_transfer(transfer);
}
Example #6
0
static void susb_issue_call(struct aura_node *node, struct aura_buffer *buf)
{
	struct aura_object *o = buf->object;
	struct usb_dev_info *inf = aura_get_transportdata(node);
	uint8_t rqtype;
	uint16_t wIndex, wValue, *ptr;
	size_t datalen; /*Actual data in packet, save for setup */

	if (o->retlen) {
		rqtype = LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_IN;
		datalen = o->retlen;
	} else {
		datalen = o->arglen - 2 * sizeof(uint16_t);
		rqtype = LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_OUT;
	}
	ptr = (uint16_t *)&buf->data[buf->pos];
	wValue = *ptr++;
	wIndex = *ptr++;

	memmove(&buf->data[buf->pos], ptr, datalen);

	/*
	 * VUSB-based devices (or libusb?) do not seem to play nicely when we have the
	 * setup packet with no data. Transfers may fail instantly.
	 * A typical run at my box gives:
	 *
	 * 9122 succeeded, 878 failed total 10000
	 *
	 * See tests-transports/test-susb-stability-none
	 * Adding just one byte of data to the packet fix the issue.
	 * Posible workarounds are:
	 * 1. Retry N times
	 * 2. Add just one dummy byte for the transfer
	 * Since nobody reported this workaround breaking support for their
	 * hardware - we'll do it the second way. For now.
	 */

	if (!datalen)
		datalen++; /* buffer's big enough anyway */

	/* e.g if device is big endian, but has le descriptors
	 * we have to be extra careful here
	 */

	if (node->need_endian_swap) {
		wValue = __swap16(wValue);
		wIndex = __swap16(wValue);
	}

	inf->current_buffer = buf;
	libusb_fill_control_setup((unsigned char *)buf->data, rqtype, o->id, wValue, wIndex,
				  datalen);
	libusb_fill_control_transfer(inf->ctransfer, inf->handle,
				     (unsigned char *)buf->data, cb_call_done, node, 4000);
	inf->control_retry_count = 0;
	submit_control(node);
}
Example #7
0
static void request_object(struct aura_node *node, int id)
{
	struct usb_dev_info *inf = aura_get_transportdata(node);
	libusb_fill_control_setup(inf->ctrlbuf, 
				  LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_IN,
				  RQ_GET_OBJ_INFO,
				  0, id, inf->io_buf_size - LIBUSB_CONTROL_SETUP_SIZE);
	libusb_fill_control_transfer(inf->ctransfer, inf->handle, inf->ctrlbuf, cb_parse_object, node, 1500);
	submit_control(node);	
}
Example #8
0
static void submit_call_write(struct aura_node *node, struct aura_buffer *buf)
{
	struct aura_object *o = buf->object;
	struct usb_dev_info *inf = aura_get_transportdata(node);
	
	slog(4, SLOG_DEBUG, "Writing call %s data to device, %d bytes", o->name, buf->size);
	inf->current_buffer = buf; 
	libusb_fill_control_setup((unsigned char *)buf->data,
				  LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_OUT,
				  RQ_PUT_CALL,
				  0, 0, buf->size - LIBUSB_CONTROL_SETUP_SIZE);
	libusb_fill_control_transfer(inf->ctransfer, inf->handle, 
				     (unsigned char *) buf->data, 
				     cb_call_write_done, node, 1500);
	submit_control(node);
}
Example #9
0
static void submit_event_readout(struct aura_node *node)
{
	struct usb_dev_info *inf = aura_get_transportdata(node);
	struct aura_buffer *buf = aura_buffer_request(node, inf->io_buf_size);
	if (!buf) 
		return; /* Nothing bad, we'll try again later */

	slog(0, SLOG_DEBUG, "Starting evt readout, max %d bytes, pending %d", 
	     inf->io_buf_size, inf->pending);	
	libusb_fill_control_setup((unsigned char *)buf->data,
				  LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_IN,
				  RQ_GET_EVENT,
				  0, 0, buf->size - LIBUSB_CONTROL_SETUP_SIZE);
	libusb_fill_control_transfer(inf->ctransfer, inf->handle, (unsigned char *)buf->data, 
				     cb_event_readout_done, node, 1500);
	inf->current_buffer = buf;
	submit_control(node);
}
libusb_error LibusbSoundplaneDriver::processThreadSendControl(
	libusb_device_handle *device,
	uint8_t request,
	uint16_t value,
	uint16_t index,
	const unsigned char *data,
	size_t dataSize)
{
	if (processThreadShouldStopTransfers())
	{
		return LIBUSB_ERROR_OTHER;
	}

	unsigned char *buf = static_cast<unsigned char*>(malloc(LIBUSB_CONTROL_SETUP_SIZE + dataSize));
	struct libusb_transfer *transfer;

	if (!buf)
	{
		return LIBUSB_ERROR_NO_MEM;
	}

	memcpy(buf + LIBUSB_CONTROL_SETUP_SIZE, data, dataSize);

	transfer = libusb_alloc_transfer(0);
	if (!transfer)
	{
		free(buf);
		return LIBUSB_ERROR_NO_MEM;
	}

	static constexpr auto kCtrlOut = LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_OUT;
	libusb_fill_control_setup(buf, kCtrlOut, request, value, index, dataSize);
	libusb_fill_control_transfer(transfer, device, buf, &LibusbSoundplaneDriver::processThreadControlTransferCallback, this, 1000);

	transfer->flags = LIBUSB_TRANSFER_SHORT_NOT_OK
		| LIBUSB_TRANSFER_FREE_BUFFER
		| LIBUSB_TRANSFER_FREE_TRANSFER;
	const auto result = static_cast<libusb_error>(libusb_submit_transfer(transfer));
	if (result >= 0)
	{
		mOutstandingTransfers++;
	}
	return result;
}
Example #11
0
void
cp_usb_async_write(struct cp_usb_async *cp, uint8_t mask, uint8_t value)
{
	int	p;
	uint16_t gpio_set;
	int	ret;

	if (cp->set) {
		value = (cp->value & ~mask) | (value & mask);
		mask = value ^ cp->value;
	}
	cp->set = 1;
	cp->value = value;
	gpio_set = ((uint16_t) value << 8) | mask;
	if (cp->p == MAX_OUTSTANDING)
		cp_usb_async_sync(cp);
	p = cp->p;
	if (!cp->packet[p].transfer)
		cp->packet[p].transfer = libusb_alloc_transfer(0);
	cp->packet[p].direction = packet_write;
	libusb_fill_control_setup(cp->packet[p].data,
				  0x40,			/* request */
				  0xff,			/* request type */
				  0x37e1,		/* value */
				  gpio_set,		/* index */
				  0);			/* length */

	libusb_fill_control_transfer(cp->packet[p].transfer,
				     cp->handle,
				     cp->packet[p].data,
				     cp_usb_async_transfer_callback,
				     cp,
				     CP_TIMEOUT);
	ccdbg_debug(CC_DEBUG_USB_ASYNC, "Write packet %d 0x%x 0x%x\n", p, mask, value);
	ret = libusb_submit_transfer(cp->packet[p].transfer);
	if (ret)
		fprintf(stderr, "libusb_submit_transfer failed %d\n", ret);
	cp->p++;
}
Example #12
0
static int set_mode_async(unsigned char data)
{
	unsigned char *buf = malloc(LIBUSB_CONTROL_SETUP_SIZE + 1);
	struct libusb_transfer *transfer;

	if (!buf)
		return -ENOMEM;

	transfer = libusb_alloc_transfer(0);
	if (!transfer) {
		free(buf);
		return -ENOMEM;
	}

	printf("async set mode %02x\n", data);
	libusb_fill_control_setup(buf, CTRL_OUT, USB_RQ, 0x4e, 0, 1);
	buf[LIBUSB_CONTROL_SETUP_SIZE] = data;
	libusb_fill_control_transfer(transfer, devh, buf, cb_mode_changed, NULL,
		1000);

	transfer->flags = LIBUSB_TRANSFER_SHORT_NOT_OK
		| LIBUSB_TRANSFER_FREE_BUFFER | LIBUSB_TRANSFER_FREE_TRANSFER;
	return libusb_submit_transfer(transfer);
}
Example #13
0
/**
 * cd_sensor_munki_refresh_state:
 **/
static gboolean
cd_sensor_munki_refresh_state (CdSensor *sensor, GError **error)
{
	gint retval;
	gboolean ret = FALSE;
	static guint8 *request;
	libusb_device_handle *handle;
	CdSensorMunkiPrivate *priv = cd_sensor_munki_get_private (sensor);

	/* do sync request */
	handle = cd_usb_get_device_handle (priv->usb);

	/* request new button task */
	request = g_new0 (guint8, LIBUSB_CONTROL_SETUP_SIZE + 2);
	libusb_fill_control_setup (request,
				   LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE,
				   MUNKI_REQUEST_GET_STATUS,
				   0x00, 0, 2);
	libusb_fill_control_transfer (priv->transfer_state, handle, request,
				      &cd_sensor_munki_refresh_state_transfer_cb,
				      sensor, 2000);

	/* submit transfer */
	retval = libusb_submit_transfer (priv->transfer_state);
	if (retval < 0) {
		g_set_error (error, 1, 0,
			     "failed to submit transfer: %s",
			     libusb_strerror (retval));
		goto out;
	}

	/* success */
	ret = TRUE;
out:
	return ret;
}
Example #14
0
void
Chatpad::send_ctrl(uint8_t request_type, uint8_t request, uint16_t value, uint16_t index,
                   uint8_t* data_in, uint16_t length, 
                   libusb_transfer_cb_fn callback, void* userdata)
{
  libusb_transfer* transfer = libusb_alloc_transfer(0);
  transfer->flags |= LIBUSB_TRANSFER_FREE_BUFFER;
  transfer->flags |= LIBUSB_TRANSFER_FREE_TRANSFER;

  // create and fill control buffer
  uint8_t* data = static_cast<uint8_t*>(malloc(length + 8));
  libusb_fill_control_setup(data, request_type, request, value, index, length);
  memcpy(data + 8, data_in, length);
  libusb_fill_control_transfer(transfer, m_handle, data,
                               callback, userdata, 
                               0);

  int ret;
  ret = libusb_submit_transfer(transfer);
  if (ret != LIBUSB_SUCCESS)
  {
    raise_exception(std::runtime_error, "libusb_submit_transfer(): " << usb_strerror(ret));
  }
}
Example #15
0
static int usb_start_ops(struct libusb_device_handle *hndl, void *arg)
{
	/* FixMe: Reading descriptors is synchronos. This is not needed
	 * often, but leaves a possibility of a flaky usb device to 
	 * screw up the event processing.
	 * A proper workaround would be manually reading out string descriptors
	 * from a device in an async fasion in the background. 
	 */
	int ret;
	struct usb_dev_info *inf = arg;
	struct aura_node *node = inf->node; 

	inf->handle = hndl;
	
	libusb_fill_interrupt_transfer(inf->itransfer, inf->handle, 0x81,
				       inf->ibuffer, 8, 
				       cb_interrupt, node, 10000);

	libusb_fill_control_setup(inf->ctrlbuf, 
				  LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_IN,
				  RQ_GET_DEV_INFO,
				  0, 0, inf->io_buf_size);
	libusb_fill_control_transfer(inf->ctransfer, inf->handle, inf->ctrlbuf, cb_got_dev_info, node, 1500);

	ret = libusb_submit_transfer(inf->ctransfer);
	if (ret!= 0) {
		libusb_close(inf->handle);
		return -1;
	}

	inf->state = AUSB_DEVICE_INIT; /* Change our state */
	inf->cbusy = true;

	slog(4, SLOG_DEBUG, "usb: Device opened, info packet requested");
	return 0;
};
Example #16
0
/** \ingroup syncio
 * Perform a USB control transfer.
 *
 * The direction of the transfer is inferred from the bmRequestType field of
 * the setup packet.
 *
 * The wValue, wIndex and wLength fields values should be given in host-endian
 * byte order.
 *
 * \param dev_handle a handle for the device to communicate with
 * \param bmRequestType the request type field for the setup packet
 * \param bRequest the request field for the setup packet
 * \param wValue the value field for the setup packet
 * \param wIndex the index field for the setup packet
 * \param data a suitably-sized data buffer for either input or output
 * (depending on direction bits within bmRequestType)
 * \param wLength the length field for the setup packet. The data buffer should
 * be at least this size.
 * \param timeout timeout (in millseconds) that this function should wait
 * before giving up due to no response being received. For an unlimited
 * timeout, use value 0.
 * \returns on success, the number of bytes actually transferred
 * \returns LIBUSB_ERROR_TIMEOUT if the transfer timed out
 * \returns LIBUSB_ERROR_PIPE if the control request was not supported by the
 * device
 * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected
 * \returns another LIBUSB_ERROR code on other failures
 */
API_EXPORTED int libusb_control_transfer(libusb_device_handle *dev_handle,
	uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex,
	unsigned char *data, uint16_t wLength, unsigned int timeout)
{
	struct libusb_transfer *transfer = libusb_alloc_transfer(0);
	unsigned char *buffer;
	int completed = 0;
	int r;

	if (!transfer)
		return LIBUSB_ERROR_NO_MEM;

	buffer = malloc(LIBUSB_CONTROL_SETUP_SIZE + wLength);
	if (!buffer) {
		libusb_free_transfer(transfer);
		return LIBUSB_ERROR_NO_MEM;
	}

	libusb_fill_control_setup(buffer, bmRequestType, bRequest, wValue, wIndex,
		wLength);
	if ((bmRequestType & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_OUT)
		memcpy(buffer + LIBUSB_CONTROL_SETUP_SIZE, data, wLength);

	libusb_fill_control_transfer(transfer, dev_handle, buffer,
		ctrl_transfer_cb, &completed, timeout);
	transfer->flags = LIBUSB_TRANSFER_FREE_BUFFER;
	r = libusb_submit_transfer(transfer);
	if (r < 0) {
		libusb_free_transfer(transfer);
		return r;
	}

	while (!completed) {
		r = libusb_handle_events(HANDLE_CTX(dev_handle));
		if (r < 0) {
			if (r == LIBUSB_ERROR_INTERRUPTED)
				continue;
			libusb_cancel_transfer(transfer);
			while (!completed)
				if (libusb_handle_events(HANDLE_CTX(dev_handle)) < 0)
					break;
			libusb_free_transfer(transfer);
			return r;
		}
	}

	if ((bmRequestType & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_IN)
		memcpy(data, libusb_control_transfer_get_data(transfer),
			transfer->actual_length);

	switch (transfer->status) {
	case LIBUSB_TRANSFER_COMPLETED:
		r = transfer->actual_length;
		break;
	case LIBUSB_TRANSFER_TIMED_OUT:
		r = LIBUSB_ERROR_TIMEOUT;
		break;
	case LIBUSB_TRANSFER_STALL:
		r = LIBUSB_ERROR_PIPE;
		break;
	case LIBUSB_TRANSFER_NO_DEVICE:
		r = LIBUSB_ERROR_NO_DEVICE;
		break;
	default:
		usbi_warn(HANDLE_CTX(dev_handle),
			"unrecognised status code %d", transfer->status);
		r = LIBUSB_ERROR_OTHER;
	}

	libusb_free_transfer(transfer);
	return r;
}
Example #17
0
static GSList *scan(GSList *options)
{
	GSList *usb_devices, *devices, *l;
	struct drv_context *drvc;
	struct sr_dev_inst *sdi;
	struct sr_probe *probe;
	struct dev_context *devc;
	struct sr_usb_dev_inst *usb;
	struct device_info dev_info;
	int ret, device_index, i;
	char *fw_ver_str;

	(void)options;

	devices = NULL;
	drvc = di->priv;
	drvc->instances = NULL;
	device_index = 0;

	usb_devices = sr_usb_find(drvc->sr_ctx->libusb_ctx, USB_VID_PID);

	if (usb_devices == NULL)
		return NULL;

	for (l = usb_devices; l; l = l->next) {
		usb = l->data;

		if ((ret = sl2_get_device_info(*usb, &dev_info)) < 0) {
			sr_warn("Failed to get device information: %d.", ret);
			sr_usb_dev_inst_free(usb);
			continue;
		}

		if (!(devc = g_try_malloc(sizeof(struct dev_context)))) {
			sr_err("Device instance malloc failed.");
			sr_usb_dev_inst_free(usb);
			continue;
		}

		if (!(devc->xfer_in = libusb_alloc_transfer(0))) {
			sr_err("Transfer malloc failed.");
			sr_usb_dev_inst_free(usb);
			g_free(devc);
			continue;
		}

		if (!(devc->xfer_out = libusb_alloc_transfer(0))) {
			sr_err("Transfer malloc failed.");
			sr_usb_dev_inst_free(usb);
			libusb_free_transfer(devc->xfer_in);
			g_free(devc);
			continue;
		}

		fw_ver_str = g_strdup_printf("%u.%u", dev_info.fw_ver_major,
			dev_info.fw_ver_minor);
		if (!fw_ver_str) {
			sr_err("Firmware string malloc failed.");
			sr_usb_dev_inst_free(usb);
			libusb_free_transfer(devc->xfer_in);
			libusb_free_transfer(devc->xfer_out);
			g_free(devc);
			continue;
		}

		sdi = sr_dev_inst_new(device_index, SR_ST_INACTIVE, VENDOR_NAME,
			MODEL_NAME, fw_ver_str);
		g_free(fw_ver_str);
		if (!sdi) {
			sr_err("sr_dev_inst_new failed.");
			sr_usb_dev_inst_free(usb);
			libusb_free_transfer(devc->xfer_in);
			libusb_free_transfer(devc->xfer_out);
			g_free(devc);
			continue;
		}

		sdi->priv = devc;
		sdi->driver = di;
		sdi->inst_type = SR_INST_USB;
		sdi->conn = usb;

		for (i = 0; probe_names[i]; i++) {
			probe = sr_probe_new(i, SR_PROBE_LOGIC, TRUE,
				probe_names[i]);
			sdi->probes = g_slist_append(sdi->probes, probe);
			devc->probes[i] = probe;
		}

		devc->state = STATE_IDLE;
		devc->next_state = STATE_IDLE;

		/* Set default samplerate. */
		sl2_set_samplerate(sdi, DEFAULT_SAMPLERATE);

		/* Set default capture ratio. */
		devc->capture_ratio = 0;

		/* Set default after trigger delay. */
		devc->after_trigger_delay = 0;

		memset(devc->xfer_buf_in, 0, LIBUSB_CONTROL_SETUP_SIZE +
			PACKET_LENGTH);
		memset(devc->xfer_buf_out, 0, LIBUSB_CONTROL_SETUP_SIZE +
			PACKET_LENGTH);

		libusb_fill_control_setup(devc->xfer_buf_in,
			USB_REQUEST_TYPE_IN, USB_HID_GET_REPORT,
			USB_HID_REPORT_TYPE_FEATURE, USB_INTERFACE,
			PACKET_LENGTH);
		libusb_fill_control_setup(devc->xfer_buf_out,
			USB_REQUEST_TYPE_OUT, USB_HID_SET_REPORT,
			USB_HID_REPORT_TYPE_FEATURE, USB_INTERFACE,
			PACKET_LENGTH);

		devc->xfer_data_in = devc->xfer_buf_in +
			LIBUSB_CONTROL_SETUP_SIZE;
		devc->xfer_data_out = devc->xfer_buf_out +
			LIBUSB_CONTROL_SETUP_SIZE;

		drvc->instances = g_slist_append(drvc->instances, sdi);
		devices = g_slist_append(devices, sdi);

		device_index++;
	}

	g_slist_free(usb_devices);

	return devices;
}
Example #18
0
static GSList *scan(struct sr_dev_driver *di, GSList *options)
{
	GSList *usb_devices, *devices, *l;
	struct drv_context *drvc;
	struct sr_dev_inst *sdi;
	struct dev_context *devc;
	struct sr_usb_dev_inst *usb;
	struct device_info dev_info;
	unsigned int i;
	int ret;

	(void)options;

	devices = NULL;
	drvc = di->context;
	drvc->instances = NULL;

	usb_devices = sr_usb_find(drvc->sr_ctx->libusb_ctx, USB_VID_PID);

	if (!usb_devices)
		return NULL;

	for (l = usb_devices; l; l = l->next) {
		usb = l->data;

		if ((ret = sl2_get_device_info(*usb, &dev_info)) < 0) {
			sr_warn("Failed to get device information: %d.", ret);
			sr_usb_dev_inst_free(usb);
			continue;
		}

		devc = g_malloc0(sizeof(struct dev_context));

		if (!(devc->xfer_in = libusb_alloc_transfer(0))) {
			sr_err("Transfer malloc failed.");
			sr_usb_dev_inst_free(usb);
			g_free(devc);
			continue;
		}

		if (!(devc->xfer_out = libusb_alloc_transfer(0))) {
			sr_err("Transfer malloc failed.");
			sr_usb_dev_inst_free(usb);
			libusb_free_transfer(devc->xfer_in);
			g_free(devc);
			continue;
		}

		sdi = g_malloc0(sizeof(struct sr_dev_inst));
		sdi->status = SR_ST_INACTIVE;
		sdi->vendor = g_strdup(VENDOR_NAME);
		sdi->model = g_strdup(MODEL_NAME);
		sdi->version = g_strdup_printf("%u.%u", dev_info.fw_ver_major, dev_info.fw_ver_minor);
		sdi->serial_num = g_strdup_printf("%d", dev_info.serial);
		sdi->priv = devc;
		sdi->driver = di;
		sdi->inst_type = SR_INST_USB;
		sdi->conn = usb;

		for (i = 0; i < ARRAY_SIZE(channel_names); i++)
			devc->channels[i] = sr_channel_new(sdi, i,
				SR_CHANNEL_LOGIC, TRUE, channel_names[i]);

		devc->state = STATE_IDLE;
		devc->next_state = STATE_IDLE;

		/* Set default samplerate. */
		sl2_set_samplerate(sdi, DEFAULT_SAMPLERATE);

		/* Set default capture ratio. */
		devc->capture_ratio = 0;

		/* Set default after trigger delay. */
		devc->after_trigger_delay = 0;

		memset(devc->xfer_buf_in, 0, LIBUSB_CONTROL_SETUP_SIZE +
			PACKET_LENGTH);
		memset(devc->xfer_buf_out, 0, LIBUSB_CONTROL_SETUP_SIZE +
			PACKET_LENGTH);

		libusb_fill_control_setup(devc->xfer_buf_in,
			USB_REQUEST_TYPE_IN, USB_HID_GET_REPORT,
			USB_HID_REPORT_TYPE_FEATURE, USB_INTERFACE,
			PACKET_LENGTH);
		libusb_fill_control_setup(devc->xfer_buf_out,
			USB_REQUEST_TYPE_OUT, USB_HID_SET_REPORT,
			USB_HID_REPORT_TYPE_FEATURE, USB_INTERFACE,
			PACKET_LENGTH);

		devc->xfer_data_in = devc->xfer_buf_in +
			LIBUSB_CONTROL_SETUP_SIZE;
		devc->xfer_data_out = devc->xfer_buf_out +
			LIBUSB_CONTROL_SETUP_SIZE;

		drvc->instances = g_slist_append(drvc->instances, sdi);
		devices = g_slist_append(devices, sdi);
	}

	g_slist_free(usb_devices);

	return devices;
}
Example #19
0
bool CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress)
{
	u32 Parameter		= Memory::Read_U32(_CommandAddress + 0xC);
	u32 BufferIn		= Memory::Read_U32(_CommandAddress + 0x10);
	u32 BufferInSize	= Memory::Read_U32(_CommandAddress + 0x14);
	u32 BufferOut		= Memory::Read_U32(_CommandAddress + 0x18);
	u32 BufferOutSize	= Memory::Read_U32(_CommandAddress + 0x1C);

	u32 ReturnValue = 0;
	switch (Parameter)
	{
	case IOCTL_HID_GET_ATTACHED:
	{
		DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Get Attached) (BufferIn: (%08x, %i), BufferOut: (%08x, %i)",
			BufferIn, BufferInSize, BufferOut, BufferOutSize);
		deviceCommandAddress = _CommandAddress;
		return false;
		break;
	}
	case IOCTL_HID_OPEN:
	{
		DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Open) (BufferIn: (%08x, %i), BufferOut: (%08x, %i)",
			BufferIn, BufferInSize, BufferOut, BufferOutSize);

		//hid version, apparently
		ReturnValue = 0x40001;
		break;
	}
	case IOCTL_HID_SET_SUSPEND:
	{
		DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Set Suspend) (BufferIn: (%08x, %i), BufferOut: (%08x, %i)",
			BufferIn, BufferInSize, BufferOut, BufferOutSize);
		// not actually implemented in IOS
		ReturnValue = 0;
		break;
	}
	case IOCTL_HID_CANCEL_INTERRUPT:
	{
		DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Cancel Interrupt) (BufferIn: (%08x, %i), BufferOut: (%08x, %i)",
			BufferIn, BufferInSize, BufferOut, BufferOutSize);
		ReturnValue = 0;
		break;
	}
	case IOCTL_HID_CONTROL:
	{
		/*
			ERROR CODES:
			-4 Cant find device specified
		*/

		u32 dev_num  = Memory::Read_U32(BufferIn+0x10);
		u8 bmRequestType = Memory::Read_U8(BufferIn+0x14);
		u8 bRequest = Memory::Read_U8(BufferIn+0x15);
		u16 wValue = Memory::Read_U16(BufferIn+0x16);
		u16 wIndex = Memory::Read_U16(BufferIn+0x18);
		u16 wLength = Memory::Read_U16(BufferIn+0x1A);
		u32 data = Memory::Read_U32(BufferIn+0x1C);

		ReturnValue = HIDERR_NO_DEVICE_FOUND;

		libusb_device_handle * dev_handle = GetDeviceByDevNum(dev_num);

		if (dev_handle == NULL)
		{
			DEBUG_LOG(WII_IPC_HID, "Could not find handle: %X", dev_num);
			break;
		}
		struct libusb_transfer *transfer = libusb_alloc_transfer(0);
		transfer->flags |= LIBUSB_TRANSFER_FREE_BUFFER | LIBUSB_TRANSFER_FREE_TRANSFER;

		u8 * buffer = (u8*)malloc(wLength + LIBUSB_CONTROL_SETUP_SIZE);
		libusb_fill_control_setup(buffer, bmRequestType, bRequest, wValue, wIndex, wLength);
		memcpy(buffer + LIBUSB_CONTROL_SETUP_SIZE, Memory::GetPointer(data), wLength);
		libusb_fill_control_transfer(transfer, dev_handle, buffer, handleUsbUpdates, (void*)(size_t)_CommandAddress, /* no timeout */ 0);
		libusb_submit_transfer(transfer);

		//DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Control)(%02X, %02X) (BufferIn: (%08x, %i), BufferOut: (%08x, %i)",
		//		  bmRequestType, bRequest, BufferIn, BufferInSize, BufferOut, BufferOutSize);

		// It's the async way!
		return false;
		break;
	}
	case IOCTL_HID_INTERRUPT_OUT:
	case IOCTL_HID_INTERRUPT_IN:
	{
		u32 dev_num  = Memory::Read_U32(BufferIn+0x10);
		u32 endpoint = Memory::Read_U32(BufferIn+0x14);
		u32 length = Memory::Read_U32(BufferIn+0x18);

		u32 data = Memory::Read_U32(BufferIn+0x1C);

		ReturnValue = HIDERR_NO_DEVICE_FOUND;

		libusb_device_handle * dev_handle = GetDeviceByDevNum(dev_num);

		if (dev_handle == NULL)
		{
			DEBUG_LOG(WII_IPC_HID, "Could not find handle: %X", dev_num);
			break;
		}

		struct libusb_transfer *transfer = libusb_alloc_transfer(0);
		transfer->flags |= LIBUSB_TRANSFER_FREE_TRANSFER;
		libusb_fill_interrupt_transfer(transfer, dev_handle, endpoint, Memory::GetPointer(data), length,
									   handleUsbUpdates, (void*)(size_t)_CommandAddress, 0);
		libusb_submit_transfer(transfer);

		//DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Interrupt %s)(%d,%d,%X) (BufferIn: (%08x, %i), BufferOut: (%08x, %i)",
		//	Parameter == IOCTL_HID_INTERRUPT_IN ? "In" : "Out", endpoint, length, data, BufferIn, BufferInSize, BufferOut, BufferOutSize);

		// It's the async way!
		return false;
		break;
	}
	case IOCTL_HID_SHUTDOWN:
	{
		std::lock_guard<std::mutex> lk(s_device_list_reply);
		if (deviceCommandAddress != 0){
			Memory::Write_U32(0xFFFFFFFF, Memory::Read_U32(deviceCommandAddress + 0x18));

			Memory::Write_U32(8, deviceCommandAddress);
			// IOS seems to write back the command that was responded to
			Memory::Write_U32(/*COMMAND_IOCTL*/ 6, deviceCommandAddress + 8);

			// Return value
			Memory::Write_U32(-1, deviceCommandAddress + 4);
			WII_IPC_HLE_Interface::EnqueReplyCallback(deviceCommandAddress);
			deviceCommandAddress = 0;
		}
		DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Shutdown) (BufferIn: (%08x, %i), BufferOut: (%08x, %i)",
			BufferIn, BufferInSize, BufferOut, BufferOutSize);
		break;
	}
	default:
	{
		DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(0x%x) (BufferIn: (%08x, %i), BufferOut: (%08x, %i)",
			Parameter, BufferIn, BufferInSize, BufferOut, BufferOutSize);
		break;
	}
	}

	Memory::Write_U32(ReturnValue, _CommandAddress + 4);

	return true;
}