Esempio n. 1
0
/**
* コントロールメッセージ送信処理(usb_control_msgのパススルー関数)
* @author University of Tsukuba
* @param usb_control_msg()と同様
* @return int usb_control_msg()の戻り値と同様
* @since 2008.02
* @version 1.0
*/
int IDMan_StUsbControlMsg(struct ID_USB_DEV_HANDLE *dev, int requesttype, int request,
						  int value, int index, char *bytes, int size, int timeout)
{
	return usb_control_msg((struct usb_dev_handle*)dev,requesttype,  request,
							  value, index, bytes,  size,  timeout);
}
Esempio n. 2
0
File: ipaq.c Progetto: asmblur/SynCE
static int ipaq_open(struct usb_serial_port *port, struct file *filp)
{
	struct usb_serial	*serial = port->serial;
	struct ipaq_private	*priv;
	struct ipaq_packet	*pkt;
	int			i, result = 0;
	int			retries = connect_retries;

	dbg("%s - port %d", __func__, port->number);

	bytes_in = 0;
	bytes_out = 0;
	priv = kmalloc(sizeof(struct ipaq_private), GFP_KERNEL);
	if (priv == NULL) {
		err("%s - Out of memory", __func__);
		return -ENOMEM;
	}
	usb_set_serial_port_data(port, priv);
	priv->active = 0;
	priv->queue_len = 0;
	priv->free_len = 0;
	INIT_LIST_HEAD(&priv->queue);
	INIT_LIST_HEAD(&priv->freelist);

	for (i = 0; i < URBDATA_QUEUE_MAX / PACKET_SIZE; i++) {
		pkt = kmalloc(sizeof(struct ipaq_packet), GFP_KERNEL);
		if (pkt == NULL) {
			goto enomem;
		}
		pkt->data = kmalloc(PACKET_SIZE, GFP_KERNEL);
		if (pkt->data == NULL) {
			kfree(pkt);
			goto enomem;
		}
		pkt->len = 0;
		pkt->written = 0;
		INIT_LIST_HEAD(&pkt->list);
		list_add(&pkt->list, &priv->freelist);
		priv->free_len += PACKET_SIZE;
	}

	/*
	 * Force low latency on. This will immediately push data to the line
	 * discipline instead of queueing.
	 */

	port->tty->low_latency = 1;
	port->tty->raw = 1;
	port->tty->real_raw = 1;

	/*
	 * Lose the small buffers usbserial provides. Make larger ones.
	 */

	kfree(port->bulk_in_buffer);
	kfree(port->bulk_out_buffer);
	port->bulk_in_buffer = kmalloc(URBDATA_SIZE, GFP_KERNEL);
	if (port->bulk_in_buffer == NULL) {
		port->bulk_out_buffer = NULL; /* prevent double free */
		goto enomem;
	}
	port->bulk_out_buffer = kmalloc(URBDATA_SIZE, GFP_KERNEL);
	if (port->bulk_out_buffer == NULL) {
		kfree(port->bulk_in_buffer);
		port->bulk_in_buffer = NULL;
		goto enomem;
	}
	port->read_urb->transfer_buffer = port->bulk_in_buffer;
	port->write_urb->transfer_buffer = port->bulk_out_buffer;
	port->read_urb->transfer_buffer_length = URBDATA_SIZE;
	port->bulk_out_size = port->write_urb->transfer_buffer_length = URBDATA_SIZE;
	
	msleep(1000*initial_wait);

	/*
	 * Send out control message observed in win98 sniffs. Not sure what
	 * it does, but from empirical observations, it seems that the device
	 * will start the chat sequence once one of these messages gets
	 * through. Since this has a reasonably high failure rate, we retry
	 * several times.
	 */

	while (retries--) {
		result = usb_control_msg(serial->dev,
				usb_sndctrlpipe(serial->dev, 0), 0x22, 0x21,
				0x1, 0, NULL, 0, 100);
		if (!result)
			break;

		msleep(1000);
	}

	if (!retries && result) {
		err("%s - failed doing control urb, error %d", __func__,
		    result);
		goto error;
	}

	/* Start reading from the device */
	usb_fill_bulk_urb(port->read_urb, serial->dev,
		      usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress),
		      port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length,
		      ipaq_read_bulk_callback, port);

	result = usb_submit_urb(port->read_urb, GFP_KERNEL);
	if (result) {
		err("%s - failed submitting read urb, error %d", __func__, result);
		goto error;
	}

	return 0;

enomem:
	result = -ENOMEM;
	err("%s - Out of memory", __func__);
error:
	ipaq_destroy_lists(port);
	kfree(priv);
	return result;
}
Esempio n. 3
0
/**
 *	ld_usb_write
 */
static ssize_t ld_usb_write(struct file *file, const char __user *buffer,
			    size_t count, loff_t *ppos)
{
	struct ld_usb *dev;
	size_t bytes_to_write;
	int retval = 0;

	dev = file->private_data;

	/* verify that we actually have some data to write */
	if (count == 0)
		goto exit;

	/* lock this object */
	if (mutex_lock_interruptible(&dev->mutex)) {
		retval = -ERESTARTSYS;
		goto exit;
	}

	/* verify that the device wasn't unplugged */
	if (dev->intf == NULL) {
		retval = -ENODEV;
		err("No device or device unplugged %d\n", retval);
		goto unlock_exit;
	}

	/* wait until previous transfer is finished */
	if (dev->interrupt_out_busy) {
		if (file->f_flags & O_NONBLOCK) {
			retval = -EAGAIN;
			goto unlock_exit;
		}
		retval = wait_event_interruptible(dev->write_wait, !dev->interrupt_out_busy);
		if (retval < 0) {
			goto unlock_exit;
		}
	}

	/* write the data into interrupt_out_buffer from userspace */
	bytes_to_write = min(count, write_buffer_size*dev->interrupt_out_endpoint_size);
	if (bytes_to_write < count)
		dev_warn(&dev->intf->dev, "Write buffer overflow, %zd bytes dropped\n",count-bytes_to_write);
	dbg_info(&dev->intf->dev, "%s: count = %zd, bytes_to_write = %zd\n", __func__, count, bytes_to_write);

	if (copy_from_user(dev->interrupt_out_buffer, buffer, bytes_to_write)) {
		retval = -EFAULT;
		goto unlock_exit;
	}

	if (dev->interrupt_out_endpoint == NULL) {
		/* try HID_REQ_SET_REPORT=9 on control_endpoint instead of interrupt_out_endpoint */
		retval = usb_control_msg(interface_to_usbdev(dev->intf),
					 usb_sndctrlpipe(interface_to_usbdev(dev->intf), 0),
					 9,
					 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
					 1 << 8, 0,
					 dev->interrupt_out_buffer,
					 bytes_to_write,
					 USB_CTRL_SET_TIMEOUT * HZ);
		if (retval < 0)
			err("Couldn't submit HID_REQ_SET_REPORT %d\n", retval);
		goto unlock_exit;
	}

	/* send off the urb */
	usb_fill_int_urb(dev->interrupt_out_urb,
			 interface_to_usbdev(dev->intf),
			 usb_sndintpipe(interface_to_usbdev(dev->intf),
					dev->interrupt_out_endpoint->bEndpointAddress),
			 dev->interrupt_out_buffer,
			 bytes_to_write,
			 ld_usb_interrupt_out_callback,
			 dev,
			 dev->interrupt_out_interval);

	dev->interrupt_out_busy = 1;
	wmb();

	retval = usb_submit_urb(dev->interrupt_out_urb, GFP_KERNEL);
	if (retval) {
		dev->interrupt_out_busy = 0;
		err("Couldn't submit interrupt_out_urb %d\n", retval);
		goto unlock_exit;
	}
	retval = bytes_to_write;

unlock_exit:
	/* unlock the device */
	mutex_unlock(&dev->mutex);

exit:
	return retval;
}
Esempio n. 4
0
static int kobil_open (struct usb_serial_port *port, struct file *filp)
{
	int i, result = 0;
	struct kobil_private *priv;
	unsigned char *transfer_buffer;
	int transfer_buffer_length = 8;
	int write_urb_transfer_buffer_length = 8;

	dbg("%s - port %d", __FUNCTION__, port->number);
	priv = usb_get_serial_port_data(port);
	priv->line_state = 0;

	// someone sets the dev to 0 if the close method has been called
	port->interrupt_in_urb->dev = port->serial->dev;


	/* force low_latency on so that our tty_push actually forces
	 * the data through, otherwise it is scheduled, and with high
	 * data rates (like with OHCI) data can get lost.
	 */
	port->tty->low_latency = 1;

	// without this, every push_tty_char is echoed :-(  
	port->tty->termios->c_lflag = 0;
	port->tty->termios->c_lflag &= ~(ISIG | ICANON | ECHO | IEXTEN | XCASE);
	port->tty->termios->c_iflag = IGNBRK | IGNPAR | IXOFF;
	port->tty->termios->c_oflag &= ~ONLCR; // do NOT translate CR to CR-NL (0x0A -> 0x0A 0x0D)
	
	// set up internal termios structure 
	priv->internal_termios.c_iflag = port->tty->termios->c_iflag;
	priv->internal_termios.c_oflag = port->tty->termios->c_oflag;
	priv->internal_termios.c_cflag = port->tty->termios->c_cflag;
	priv->internal_termios.c_lflag = port->tty->termios->c_lflag;

	for (i=0; i<NCCS; i++) {
		priv->internal_termios.c_cc[i] = port->tty->termios->c_cc[i];
	}
	
	// allocate memory for transfer buffer
	transfer_buffer = kzalloc(transfer_buffer_length, GFP_KERNEL);
	if (! transfer_buffer) {
		return -ENOMEM;
	}
	
	// allocate write_urb
	if (!port->write_urb) { 
		dbg("%s - port %d  Allocating port->write_urb", __FUNCTION__, port->number);
		port->write_urb = usb_alloc_urb(0, GFP_KERNEL);  
		if (!port->write_urb) {
			dbg("%s - port %d usb_alloc_urb failed", __FUNCTION__, port->number);
			kfree(transfer_buffer);
			return -ENOMEM;
		}
	}

	// allocate memory for write_urb transfer buffer
	port->write_urb->transfer_buffer = kmalloc(write_urb_transfer_buffer_length, GFP_KERNEL);
	if (! port->write_urb->transfer_buffer) {
		kfree(transfer_buffer);
		usb_free_urb(port->write_urb);
		port->write_urb = NULL;
		return -ENOMEM;
	} 

	// get hardware version
	result = usb_control_msg( port->serial->dev, 
				  usb_rcvctrlpipe(port->serial->dev, 0 ), 
				  SUSBCRequest_GetMisc,
				  USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_IN,
				  SUSBCR_MSC_GetHWVersion,
				  0,
				  transfer_buffer,
				  transfer_buffer_length,
				  KOBIL_TIMEOUT
		);
	dbg("%s - port %d Send get_HW_version URB returns: %i", __FUNCTION__, port->number, result);
	dbg("Harware version: %i.%i.%i", transfer_buffer[0], transfer_buffer[1], transfer_buffer[2] );
	
	// get firmware version
	result = usb_control_msg( port->serial->dev, 
				  usb_rcvctrlpipe(port->serial->dev, 0 ), 
				  SUSBCRequest_GetMisc,
				  USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_IN,
				  SUSBCR_MSC_GetFWVersion,
				  0,
				  transfer_buffer,
				  transfer_buffer_length,
				  KOBIL_TIMEOUT
		);
	dbg("%s - port %d Send get_FW_version URB returns: %i", __FUNCTION__, port->number, result);
	dbg("Firmware version: %i.%i.%i", transfer_buffer[0], transfer_buffer[1], transfer_buffer[2] );

	if (priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID || priv->device_type == KOBIL_ADAPTER_K_PRODUCT_ID) {
		// Setting Baudrate, Parity and Stopbits
		result = usb_control_msg( port->serial->dev, 
					  usb_rcvctrlpipe(port->serial->dev, 0 ), 
					  SUSBCRequest_SetBaudRateParityAndStopBits,
					  USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT,
					  SUSBCR_SBR_9600 | SUSBCR_SPASB_EvenParity | SUSBCR_SPASB_1StopBit,
					  0,
					  transfer_buffer,
					  0,
					  KOBIL_TIMEOUT
			);
		dbg("%s - port %d Send set_baudrate URB returns: %i", __FUNCTION__, port->number, result);
		
		// reset all queues
		result = usb_control_msg( port->serial->dev, 
					  usb_rcvctrlpipe(port->serial->dev, 0 ), 
					  SUSBCRequest_Misc,
					  USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT,
					  SUSBCR_MSC_ResetAllQueues,
					  0,
					  transfer_buffer,
					  0,
					  KOBIL_TIMEOUT
			);
		dbg("%s - port %d Send reset_all_queues URB returns: %i", __FUNCTION__, port->number, result);
	}
	if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID || priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID ||
	    priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID) {
		// start reading (Adapter B 'cause PNP string)
		result = usb_submit_urb( port->interrupt_in_urb, GFP_ATOMIC  ); 
		dbg("%s - port %d Send read URB returns: %i", __FUNCTION__, port->number, result);
	}

	kfree(transfer_buffer);
	return 0;
}
Esempio n. 5
0
static int  kobil_ioctl(struct usb_serial_port *port, struct file *file,
			unsigned int cmd, unsigned long arg)
{
	struct kobil_private * priv;
	int result;
	unsigned short urb_val = 0;
	unsigned char *transfer_buffer;
	int transfer_buffer_length = 8;
	char *settings;
	void __user *user_arg = (void __user *)arg;

	priv = usb_get_serial_port_data(port);
	if ((priv->device_type == KOBIL_USBTWIN_PRODUCT_ID) || (priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID)) {
		// This device doesn't support ioctl calls
		return 0;
	}

	switch (cmd) {
	case TCGETS:   // 0x5401
		if (!access_ok(VERIFY_WRITE, user_arg, sizeof(struct ktermios))) {
			dbg("%s - port %d Error in access_ok", __FUNCTION__, port->number);
			return -EFAULT;
		}
		if (kernel_termios_to_user_termios((struct ktermios __user *)arg,
						   &priv->internal_termios))
			return -EFAULT;
		return 0;

	case TCSETS:   // 0x5402
		if (!(port->tty->termios)) {
			dbg("%s - port %d Error: port->tty->termios is NULL", __FUNCTION__, port->number);
			return -ENOTTY;
		}
		if (!access_ok(VERIFY_READ, user_arg, sizeof(struct ktermios))) {
			dbg("%s - port %d Error in access_ok", __FUNCTION__, port->number);
			return -EFAULT;
		}
		if (user_termios_to_kernel_termios(&priv->internal_termios,
						   (struct ktermios __user *)arg))
			return -EFAULT;
		
		settings = kzalloc(50, GFP_KERNEL);
		if (! settings) {
			return -ENOBUFS;
		}

		switch (priv->internal_termios.c_cflag & CBAUD) {
		case B1200:
			urb_val = SUSBCR_SBR_1200;
			strcat(settings, "1200 ");
			break;
		case B9600:
		default:
			urb_val = SUSBCR_SBR_9600;
			strcat(settings, "9600 ");
			break;
		}

		urb_val |= (priv->internal_termios.c_cflag & CSTOPB) ? SUSBCR_SPASB_2StopBits : SUSBCR_SPASB_1StopBit;
		strcat(settings, (priv->internal_termios.c_cflag & CSTOPB) ? "2 StopBits " : "1 StopBit ");

		if (priv->internal_termios.c_cflag & PARENB) {
			if  (priv->internal_termios.c_cflag & PARODD) {
				urb_val |= SUSBCR_SPASB_OddParity;
				strcat(settings, "Odd Parity");
			} else {
				urb_val |= SUSBCR_SPASB_EvenParity;
				strcat(settings, "Even Parity");
			}
		} else {
			urb_val |= SUSBCR_SPASB_NoParity;
			strcat(settings, "No Parity");
		}
		dbg("%s - port %d setting port to: %s", __FUNCTION__, port->number, settings );

		result = usb_control_msg( port->serial->dev, 
					  usb_rcvctrlpipe(port->serial->dev, 0 ), 
					  SUSBCRequest_SetBaudRateParityAndStopBits,
					  USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT,
					  urb_val,
					  0,
					  settings,
					  0,
					  KOBIL_TIMEOUT
			);

		dbg("%s - port %d Send set_baudrate URB returns: %i", __FUNCTION__, port->number, result);
		kfree(settings);
		return 0;

	case TCFLSH:   // 0x540B
		transfer_buffer = kmalloc(transfer_buffer_length, GFP_KERNEL);
		if (! transfer_buffer) {
		 	return -ENOBUFS;
		}

		result = usb_control_msg( port->serial->dev, 
		 			  usb_rcvctrlpipe(port->serial->dev, 0 ), 
					  SUSBCRequest_Misc,
					  USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT,
					  SUSBCR_MSC_ResetAllQueues,
					  0,
					  NULL,//transfer_buffer,
					  0,
					  KOBIL_TIMEOUT
			);
		
		dbg("%s - port %d Send reset_all_queues (FLUSH) URB returns: %i", __FUNCTION__, port->number, result);

		kfree(transfer_buffer);
		return ((result < 0) ? -EFAULT : 0);

	}
	return -ENOIOCTLCMD;
}
Esempio n. 6
0
static int kobil_open(struct tty_struct *tty, struct usb_serial_port *port)
{
	struct device *dev = &port->dev;
	int result = 0;
	struct kobil_private *priv;
	unsigned char *transfer_buffer;
	int transfer_buffer_length = 8;

	priv = usb_get_serial_port_data(port);

	/* allocate memory for transfer buffer */
	transfer_buffer = kzalloc(transfer_buffer_length, GFP_KERNEL);
	if (!transfer_buffer)
		return -ENOMEM;

	/* get hardware version */
	result = usb_control_msg(port->serial->dev,
			  usb_rcvctrlpipe(port->serial->dev, 0),
			  SUSBCRequest_GetMisc,
			  USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_IN,
			  SUSBCR_MSC_GetHWVersion,
			  0,
			  transfer_buffer,
			  transfer_buffer_length,
			  KOBIL_TIMEOUT
	);
	dev_dbg(dev, "%s - Send get_HW_version URB returns: %i\n", __func__, result);
	dev_dbg(dev, "Hardware version: %i.%i.%i\n", transfer_buffer[0],
		transfer_buffer[1], transfer_buffer[2]);

	/* get firmware version */
	result = usb_control_msg(port->serial->dev,
			  usb_rcvctrlpipe(port->serial->dev, 0),
			  SUSBCRequest_GetMisc,
			  USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_IN,
			  SUSBCR_MSC_GetFWVersion,
			  0,
			  transfer_buffer,
			  transfer_buffer_length,
			  KOBIL_TIMEOUT
	);
	dev_dbg(dev, "%s - Send get_FW_version URB returns: %i\n", __func__, result);
	dev_dbg(dev, "Firmware version: %i.%i.%i\n", transfer_buffer[0],
		transfer_buffer[1], transfer_buffer[2]);

	if (priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID ||
			priv->device_type == KOBIL_ADAPTER_K_PRODUCT_ID) {
		/* Setting Baudrate, Parity and Stopbits */
		result = usb_control_msg(port->serial->dev,
			  usb_sndctrlpipe(port->serial->dev, 0),
			  SUSBCRequest_SetBaudRateParityAndStopBits,
			  USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT,
			  SUSBCR_SBR_9600 | SUSBCR_SPASB_EvenParity |
							SUSBCR_SPASB_1StopBit,
			  0,
			  NULL,
			  0,
			  KOBIL_TIMEOUT
		);
		dev_dbg(dev, "%s - Send set_baudrate URB returns: %i\n", __func__, result);

		/* reset all queues */
		result = usb_control_msg(port->serial->dev,
			  usb_sndctrlpipe(port->serial->dev, 0),
			  SUSBCRequest_Misc,
			  USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT,
			  SUSBCR_MSC_ResetAllQueues,
			  0,
			  NULL,
			  0,
			  KOBIL_TIMEOUT
		);
		dev_dbg(dev, "%s - Send reset_all_queues URB returns: %i\n", __func__, result);
	}
	if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID ||
	    priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID ||
	    priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID) {
		/* start reading (Adapter B 'cause PNP string) */
		result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
		dev_dbg(dev, "%s - Send read URB returns: %i\n", __func__, result);
	}

	kfree(transfer_buffer);
	return 0;
}
Esempio n. 7
0
int USBDriver_Impl_Libusb::ControlMessage( int iType, int iRequest, int iValue, int iIndex, char *pData, int iSize, int iTimeout )
{
	return usb_control_msg( m_pHandle, iType, iRequest, iValue, iIndex, pData, iSize, iTimeout );
}
int usb_hub_port1_power_ctr(int value)
//main (int argc, const char *argv[])
{
  int busnum = 0, devnum = 0;
  int cmd = COMMAND_SET_NONE;
  int port = 1;
  //int value = 0;
  int request, feature, index;
  int result = 0;
  int listing = 0;
  int verbose = 0;
  int hub = -1;
  usb_dev_handle *uh = NULL;

  int i;




#if 0
  if (argc == 1)
    listing = 1;

  for (i = 1; i < argc; i++)
    if (argv[i][0] == '-')
      switch (argv[i][1])
	{
	case 'h':
	  if (++i >= argc || busnum > 0 || devnum > 0)
	    exit_with_usage (argv[0]);
	  hub = atoi (argv[i]);
	  break;

	case 'b':
	  if (++i >= argc || hub >= 0)
	    exit_with_usage (argv[0]);
	  busnum = atoi (argv[i]);
	  break;

	case 'd':
	  if (++i >= argc || hub >= 0)
	    exit_with_usage (argv[0]);
	  devnum = atoi (argv[i]);
	  break;

	case 'P':
	  if (++i >= argc)
	    exit_with_usage (argv[0]);
	  port = atoi (argv[i]);
	  break;

	case 'l':
	  if (cmd != COMMAND_SET_NONE)
	    exit_with_usage (argv[0]);
	  if (++i < argc)
	    value = atoi (argv[i]);
	  else
	    value = HUB_LED_GREEN;
	  cmd = COMMAND_SET_LED;
	  break;

	case 'p':
	  if (cmd != COMMAND_SET_NONE)
	    exit_with_usage (argv[0]);
	  if (++i < argc)
	    value = atoi (argv[i]);
	  else
	    value= 0;
	  cmd = COMMAND_SET_POWER;
	  break;

	case 'v':
	  verbose = 1;
	  if (argc == 2)
	    listing = 1;
	  break;

	default:
	  exit_with_usage (argv[0]);
	}
    else
      exit_with_usage (argv[0]);



  if ((busnum > 0 && devnum <= 0) || (busnum <= 0 && devnum > 0))
    /* BUS is specified, but DEV is'nt, or ... */
    exit_with_usage (argv[0]);
#else
    listing = 1;
    int return_busnum, return_devnum ;
    int *p_return_busnum = & return_busnum ;
    int *p_return_devnum = & return_devnum ;

#endif


  /* Default is the hub #0 */
  if (hub < 0 && busnum == 0)
    hub = 0;

  /* Default is POWER */
  if (cmd == COMMAND_SET_NONE)
    cmd = COMMAND_SET_POWER;

  usb_init ();
  usb_find_busses ();
  usb_find_devices ();


  if (
  usb_find_hubs (
  p_return_busnum,p_return_devnum     
    ,listing, verbose, busnum, devnum, hub) 
  //usb_find_hubs (listing, verbose, busnum, devnum, hub) 
    <= 0)
    {
  fprintf (stderr, "No hubs found.\n");
  exit (1);
    }
  else
    {
      //printf ("Hub %d:%d\n",return_busnum,return_devnum);
  busnum=return_busnum;
  devnum=return_devnum;
    }

#if 0
  if (listing)
    exit (0);
#endif

  if (hub < 0)
    hub = get_hub (busnum, devnum);

  if (hub >= 0 && hub < number_of_hubs_with_feature)
    uh = usb_open (hubs[hub].dev);

  if (uh == NULL)
    {
      fprintf (stderr, "Device not found.\n");
      result = 1;
    }
  else
    {
      if (cmd == COMMAND_SET_POWER)
	if (value)
	  {
	    request = USB_REQ_SET_FEATURE;
	    feature = USB_PORT_FEAT_POWER;
	    index = port;
	  }
	else
	  {
	    request = USB_REQ_CLEAR_FEATURE;
	    feature = USB_PORT_FEAT_POWER;
	    index = port;
	  }
      else
	{
	  request = USB_REQ_SET_FEATURE;
	  feature = USB_PORT_FEAT_INDICATOR;
	  index = (value << 8) | port;
	}

      if (verbose)
	printf ("Send control message (REQUEST=%d, FEATURE=%d, INDEX=%d)\n",
		request, feature, index);

      if (usb_control_msg (uh, USB_RT_PORT, request, feature, index,
			   NULL, 0, CTRL_TIMEOUT) < 0)
	{
	  perror ("failed to control.\n");
	  result = 1;
	}

      if (verbose)
	hub_port_status (uh, hubs[hub].nport);

      usb_close (uh);
    }

  //exit (result);
  return (result);
}
Esempio n. 9
0
  int Device::controlTransfer(u_int8_t requestType, u_int8_t request,
			       u_int16_t value, u_int16_t index, u_int16_t length,
			       unsigned char *payload, int timeout)
  {
    return usb_control_msg(m_handle, requestType, request, value, index, (char *)payload, length, timeout);
  }
Esempio n. 10
0
	int KinectInternalData::SendCommand(unsigned short command, unsigned char *commandbuffer, unsigned int commandbufferlength, unsigned char *replybuffer, unsigned int replybufferlength)
	{
		int i, j, ret = 0;
		uint8_t obuf[0x2000];
		uint8_t ibuf[0x2000];
		ZeroMemory(obuf, 0x2000);
		ZeroMemory(ibuf, 0x2000);

		cam_hdr *chdr = (cam_hdr *)obuf;
		cam_hdr *rhdr = (cam_hdr *)ibuf;		

		chdr->cmd = command;
		chdr->tag = mCommandTag;
		chdr->len = commandbufferlength / 2;
		chdr->magic[0] = 0x47;
		chdr->magic[1] = 0x4d;


		memcpy (obuf + sizeof (*chdr), commandbuffer, commandbufferlength);


		ret = usb_control_msg(mDeviceHandle, 0x40, 0, 0, 0, (char*)obuf, commandbufferlength + sizeof (cam_hdr), 1600);
		//ret = usb_control_msg(mDeviceHandle, 0x40, 0, 0, 0, (char*)ibuf, 0x200, 1600);
		if (ret < 0)
		{
			ErrorMessage("SendCommand: Failed to send control message! (%d)\n", ret);

			return ret;
		}

		do
		{

			ret = usb_control_msg(mDeviceHandle, 0xc0, 0, 0, 0, (char*)ibuf, 0x200, 1600);
			Sleep(10);
		}
		while (ret == 0);

		TraceMessage("Control reply: %d\n", ret);
		if (ret < sizeof (cam_hdr))
		{
			ErrorMessage ("SendCommand: Input control transfer failed (%d)\n", ret);
			return ret;
		}
		ret -= sizeof (cam_hdr);

		if (rhdr->magic[0] != 0x52 || rhdr->magic[1] != 0x42)
		{
			ErrorMessage ("SendCommand: Bad magic %02x %02x\n", rhdr->magic[0], rhdr->magic[1]);
			return -1;
		}
		if (rhdr->cmd != chdr->cmd)
		{
			ErrorMessage ("SendCommand: Bad cmd %02x != %02x\n", rhdr->cmd, chdr->cmd);
			return -1;
		}
		if (rhdr->tag != chdr->tag)
		{
			ErrorMessage ("SendCommand: Bad tag %04x != %04x\n", rhdr->tag, chdr->tag);
			return -1;
		}
		if (rhdr->len != (ret / 2))
		{
			ErrorMessage ("SendCommand: Bad len %04x != %04x\n", rhdr->len, (int) (ret / 2));
			return -1;
		}

		if (ret > replybufferlength)
		{
			WarningMessage ("SendCommand: Data buffer is %d bytes long, but got %d bytes\n", replybufferlength, ret);
			memcpy (replybuffer, ibuf + sizeof (*rhdr), replybufferlength);
		}
		else
		{
			memcpy (replybuffer, ibuf + sizeof (*rhdr), ret);
		}
	

		mCommandTag++;

		return ret;
	};
static int
usb_find_hubs (
	       int *p_return_busnum //* atoi (bus->dirname)
	       ,int *p_return_devnum 
	       ,int listing, int verbose, int busnum, int devnum, int hub)
{
  struct usb_bus *busses;
  struct usb_bus *bus;

  number_of_hubs_with_feature = 0;
  busses = usb_get_busses();
  if (busses == NULL)
    {
      perror ("failed to access USB");
      return -1;
    }

  for (bus = busses; bus; bus = bus->next)
    {
      struct usb_device *dev;

      for (dev = bus->devices; dev; dev = dev->next)
	{
	  usb_dev_handle *uh;
	  int print = 0;

	  if (dev->descriptor.bDeviceClass != USB_CLASS_HUB)
	    continue;

	  if (listing
	      || (verbose
		  && ((atoi (bus->dirname) == busnum && dev->devnum == devnum)
		      || hub == number_of_hubs_with_feature)))
	    print = 1;

	  uh = usb_open (dev);

	  if (uh != NULL)
	    {
	      char buf[1024];
	      int len;
	      int nport;
	      struct usb_hub_descriptor *uhd = (struct usb_hub_descriptor *)buf;
	      if ((len = usb_control_msg (uh, USB_DIR_IN | USB_RT_HUB,
					  USB_REQ_GET_DESCRIPTOR,
					  USB_DT_HUB << 8, 0, 
					  buf, sizeof (buf), CTRL_TIMEOUT))
		  > sizeof (struct usb_hub_descriptor))
		{
		  if (!(uhd->wHubCharacteristics[0] & HUB_CHAR_PORTIND)
		      && (uhd->wHubCharacteristics[0] & HUB_CHAR_LPSM) >= 2)
		    continue;

		  if (print){
#if DEBUG_PRINT
		    printf ("Hub #%d at %s:%03d\n",
			    number_of_hubs_with_feature,
			    bus->dirname,   dev->devnum);
#endif
		    *p_return_busnum = atoi (bus->dirname);
		    *p_return_devnum = dev->devnum;
		  }

#if DEBUG_PRINT
		  switch ((uhd->wHubCharacteristics[0] & HUB_CHAR_LPSM))
		    {
		    case 0:
		      if (print)
			fprintf (stderr, " INFO: ganged switching.\n");
		      break;
		    case 1:
		      if (print)
			fprintf (stderr, " INFO: individual power switching.\n");
		      break;
		    case 2:
		    case 3:
		      if (print)
			fprintf (stderr, " WARN: No power switching.\n");
		      break;
		    }
#endif

		  if (print
		      && !(uhd->wHubCharacteristics[0] & HUB_CHAR_PORTIND))
		    fprintf (stderr, " WARN: Port indicators are NOT supported.\n");
		}
	      else
		{
		  perror ("Can't get hub descriptor");
		  usb_close (uh);
		  continue;
		}

	      nport = buf[2];
	      hubs[number_of_hubs_with_feature].busnum = atoi (bus->dirname);
	      hubs[number_of_hubs_with_feature].devnum = dev->devnum;
	      hubs[number_of_hubs_with_feature].dev = dev;
	      hubs[number_of_hubs_with_feature].indicator_support =
		(uhd->wHubCharacteristics[0] & HUB_CHAR_PORTIND)? 1 : 0;
	      hubs[number_of_hubs_with_feature].nport = nport;

	      number_of_hubs_with_feature++;

	      if (verbose)
		hub_port_status (uh, nport);

	      usb_close (uh);
	    }
	}
    }

  return number_of_hubs_with_feature;
}
Esempio n. 12
0
static void spcp8x5_set_termios(struct tty_struct *tty,
		struct usb_serial_port *port, struct ktermios *old_termios)
{
	struct usb_serial *serial = port->serial;
	struct spcp8x5_private *priv = usb_get_serial_port_data(port);
	unsigned long flags;
	unsigned int cflag = tty->termios.c_cflag;
	unsigned short uartdata;
	unsigned char buf[2] = {0, 0};
	int baud;
	int i;
	u8 control;

	/* check that they really want us to change something */
	if (old_termios && !tty_termios_hw_change(&tty->termios, old_termios))
		return;

	/* set DTR/RTS active */
	spin_lock_irqsave(&priv->lock, flags);
	control = priv->line_control;
	if (old_termios && (old_termios->c_cflag & CBAUD) == B0) {
		priv->line_control |= MCR_DTR;
		if (!(old_termios->c_cflag & CRTSCTS))
			priv->line_control |= MCR_RTS;
	}
	if (control != priv->line_control) {
		control = priv->line_control;
		spin_unlock_irqrestore(&priv->lock, flags);
		spcp8x5_set_ctrl_line(port, control);
	} else {
		spin_unlock_irqrestore(&priv->lock, flags);
	}

	/* Set Baud Rate */
	baud = tty_get_baud_rate(tty);
	switch (baud) {
	case 300:	buf[0] = 0x00;	break;
	case 600:	buf[0] = 0x01;	break;
	case 1200:	buf[0] = 0x02;	break;
	case 2400:	buf[0] = 0x03;	break;
	case 4800:	buf[0] = 0x04;	break;
	case 9600:	buf[0] = 0x05;	break;
	case 19200:	buf[0] = 0x07;	break;
	case 38400:	buf[0] = 0x09;	break;
	case 57600:	buf[0] = 0x0a;	break;
	case 115200:	buf[0] = 0x0b;	break;
	case 230400:	buf[0] = 0x0c;	break;
	case 460800:	buf[0] = 0x0d;	break;
	case 921600:	buf[0] = 0x0e;	break;
/*	case 1200000:	buf[0] = 0x0f;	break; */
/*	case 2400000:	buf[0] = 0x10;	break; */
	case 3000000:	buf[0] = 0x11;	break;
/*	case 6000000:	buf[0] = 0x12;	break; */
	case 0:
	case 1000000:
			buf[0] = 0x0b;	break;
	default:
		dev_err(&port->dev, "unsupported baudrate, using 9600\n");
	}

	/* Set Data Length : 00:5bit, 01:6bit, 10:7bit, 11:8bit */
	switch (cflag & CSIZE) {
	case CS5:
		buf[1] |= SET_UART_FORMAT_SIZE_5;
		break;
	case CS6:
		buf[1] |= SET_UART_FORMAT_SIZE_6;
		break;
	case CS7:
		buf[1] |= SET_UART_FORMAT_SIZE_7;
		break;
	default:
	case CS8:
		buf[1] |= SET_UART_FORMAT_SIZE_8;
		break;
	}

	/* Set Stop bit2 : 0:1bit 1:2bit */
	buf[1] |= (cflag & CSTOPB) ? SET_UART_FORMAT_STOP_2 :
				     SET_UART_FORMAT_STOP_1;

	/* Set Parity bit3-4 01:Odd 11:Even */
	if (cflag & PARENB) {
		buf[1] |= (cflag & PARODD) ?
		SET_UART_FORMAT_PAR_ODD : SET_UART_FORMAT_PAR_EVEN ;
	} else {
		buf[1] |= SET_UART_FORMAT_PAR_NONE;
	}
	uartdata = buf[0] | buf[1]<<8;

	i = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
			    SET_UART_FORMAT_TYPE, SET_UART_FORMAT,
			    uartdata, 0, NULL, 0, 100);
	if (i < 0)
		dev_err(&port->dev, "Set UART format %#x failed (error = %d)\n",
			uartdata, i);
	dev_dbg(&port->dev, "0x21:0x40:0:0  %d\n", i);

	if (cflag & CRTSCTS) {
		/* enable hardware flow control */
		spcp8x5_set_work_mode(port, 0x000a, SET_WORKING_MODE_U2C);
	}
}
Esempio n. 13
0
void write_rtl8225(struct net_device *dev, u8 adr, u16 data)
{

#ifdef THOMAS_3WIRE
	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
 	struct usb_device *udev = priv->udev;
	int status;

	data = (data << 4) | (u16)(adr & 0x0f);

	//
	// OUT a vendor request to ask 8051 do HW three write operation.
	//
	//printk("before write rtl8225 , data = %x\n",data);
	status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
                               		   0x04, RTL8187_REQT_WRITE,
 						   0x0000, 0x1304, &data, 2, HZ / 2);

	if (status < 0)
        {
                printk("write_rtl8225 TimeOut! status:%x\n", status);
        }
	/*mdelay(1);
	u16 Tmpdata;
	status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
                               		   0x04, RTL8187_REQT_READ,
 						   0x0000, 0x1304, &Tmpdata, 2, HZ / 2);

	if (status < 0)
        {
                printk("read_rtl8225 TimeOut! status:%x\n", status);
        }
	printk("after read rtl8225 , data = %x\n",Tmpdata);*/
	
#else 
#ifdef USE_8051_3WIRE

        struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
        struct usb_device *udev = priv->udev;
        //u8 bit;
        u16  wReg80, wReg82, wReg84;

        wReg80 = read_nic_word(dev, RFPinsOutput);
        wReg80 &= 0xfff3;
        wReg82 = read_nic_word(dev, RFPinsEnable);
        wReg84 = read_nic_word(dev, RFPinsSelect);
        // <RJ_NOTE> 3-wire should be controled by HW when we finish SW 3-wire programming. 2005.08.10, by rcnjko.
        //wReg84 &= 0xfff0;
        wReg84 &= 0xfff8; //modified by david according to windows segment code.

        // We must set SW enabled before terminating HW 3-wire, 2005.07.29, by rcnjko.
        write_nic_word(dev, RFPinsEnable, (wReg82|0x0007));     // Set To Output Enable
        write_nic_word(dev, RFPinsSelect, (wReg84|0x0007));     // Set To SW Switch
        force_pci_posting(dev);
        udelay(10); //

        write_nic_word(dev, 0x80, (BB_HOST_BANG_EN|wReg80)); // Set SI_EN (RFLE)
        force_pci_posting(dev);
        udelay(2);
        //twreg.struc.enableB = 0;
        write_nic_word(dev, 0x80, (wReg80)); // Clear SI_EN (RFLE)
        force_pci_posting(dev);
        udelay(10);

        usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
                               RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
                               adr, 0x8225, &data, 2, HZ / 2);

        write_nic_word(dev, 0x80, (BB_HOST_BANG_EN|wReg80));
        force_pci_posting(dev);
        udelay(10);

        write_nic_word(dev, 0x80, (wReg80|0x0004));
        write_nic_word(dev, 0x84, (wReg84|0x0000));// Set To SW Switch

        if(priv->card_type == USB)
                mdelay(2);
        else
                rtl8185_rf_pins_enable(dev);

#else
	int i;
	u16 out,select;
	u8 bit;
	u32 bangdata = (data << 4) | (adr & 0xf);
	struct r8180_priv *priv = ieee80211_priv(dev);
	
	out = read_nic_word(dev, RFPinsOutput) & 0xfff3;
		
	write_nic_word(dev,RFPinsEnable,
		(read_nic_word(dev,RFPinsEnable) | 0x7));
	
	select = read_nic_word(dev, RFPinsSelect);
	
	write_nic_word(dev, RFPinsSelect, select | 0x7 | 
		((priv->card_type == USB) ? 0 : SW_CONTROL_GPIO));
	
	force_pci_posting(dev);
	udelay(10);
	
	write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN );//| 0x1fff);
	
	force_pci_posting(dev);
	udelay(2);
	
	write_nic_word(dev, RFPinsOutput, out);
	
	force_pci_posting(dev);
	udelay(10);
	
	
	for(i=15; i>=0;i--){
	
		bit = (bangdata & (1<<i)) >> i;
		
		write_nic_word(dev, RFPinsOutput, bit | out);
		
		write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
		write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);

		i--;
		bit = (bangdata & (1<<i)) >> i;
		
		write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
		write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);

		write_nic_word(dev, RFPinsOutput, bit | out);

	}
	
	write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN);
	
	force_pci_posting(dev);
	udelay(10);

	write_nic_word(dev, RFPinsOutput, out | 
		((priv->card_type == USB) ? 4 : BB_HOST_BANG_EN));

	write_nic_word(dev, RFPinsSelect, select | 
		((priv->card_type == USB) ? 0 : SW_CONTROL_GPIO));	

	if(priv->card_type == USB)
		mdelay(2);
	else
		rtl8185_rf_pins_enable(dev);
#endif

#endif /*THOMAS_3WIRE*/
}
Esempio n. 14
0
/*
 * Called when a process tries to open the device file, like
 * "cat /dev/usbtherm0".
 */
static int device_open(struct inode *inode, struct file *filp)
{
	int err = 0;
	int minor = 0;
	struct usb_interface *interface = NULL;
	struct usbtherm *dev = NULL;
	char data[8];
	char *urb_transfer_buffer;

	urb_transfer_buffer = kzalloc(sizeof(data), GFP_KERNEL);

	minor = iminor(inode);

	interface = usb_find_interface(&usbtherm_driver, minor);
	if (! interface)
	{
		err = -ENODEV;
		printk(KERN_WARNING "usbtherm: Could not find USB interface!\n");
		goto error;
	}

	dev = usb_get_intfdata(interface);
	if (! dev)
	{
		err = -ENODEV;
		printk(KERN_WARNING "usbtherm: Could not get USB device!\n");
		goto error;
	}

	/*
	 * If dev is needed in for example device_read.
	 */
	/* filp->private_data = dev; */

	/*
	 * Send a custom "vendor" type status request to read
	 * the temperature value from the device.
	 */
	err = usb_control_msg(dev->usbdev,
			usb_rcvctrlpipe(dev->usbdev, USB_DIR_OUT),
			CUSTOM_REQ_TEMP, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
			0, 0, urb_transfer_buffer, sizeof(urb_transfer_buffer), 1000);

	strlcpy(data, urb_transfer_buffer, sizeof(data));
	kfree(urb_transfer_buffer);

	if (err < 0)
	{
		err = -EIO;
		goto error;
	}

	snprintf(message, MSG_LEN, "%s\n", data);

	/* printk(KERN_DEBUG "usbtherm: Device was opened"); */

	return SUCCESS;

error:
	return err;
}
Esempio n. 15
0
int gnubl(void)
{
    char    string[256];
	struct usb_bus      *bus;
	struct usb_device   *dev;
	int nBytes;
	int counter = 0;
	int doStartBootloader = 0;
	usb_dev_handle      *handle = 0;

    usb_init();
  
    usb_find_busses();
    usb_find_devices();
  
  	for(bus=usb_busses; bus; bus=bus->next){
        for(dev=bus->devices; dev; dev=dev->next){
            if(gnubl_isOurVIDandPID(dev)){
                int     len;
                handle = usb_open(dev); /* we need to open the device in order to query strings */
                if(!handle){
                    fprintf(stderr, "Warning: cannot open USB device: %s\n", usb_strerror());
                    continue;
                }
                /* now find out whether the device actually is obdev's Remote Sensor: */
                len = usbGetStringAscii(handle, dev->descriptor.iManufacturer, 0x0409, string, sizeof(string));
                if(len < 0){
                    fprintf(stderr, "warning: cannot query manufacturer for device: %s\n", usb_strerror());
                }
                /* fprintf(stderr, "seen device from vendor ->%s<-\n", string); */
                if(strcmp(string, "www.anyma.ch") == 0) {
                
					len = usbGetStringAscii(handle, dev->descriptor.iProduct, 0x0409, string, sizeof(string));
					if(len < 0){
						fprintf(stderr, "warning: cannot query product for device: %s\n", usb_strerror());
                	} else {
                		
                		doStartBootloader = 1;
						
						if (doStartBootloader) {
                			 nBytes = 	usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN,
									GNUSB_CMD_START_BOOTLOADER, 0, 0, NULL, 0, 5000);
							printf("--> Started bootloader on device \"%s\"\n", string);
							counter++;
							sleep(1);
						}
					}
                }
                usb_close(handle);
                handle = NULL;
            }
        }
    }
    if (!counter) {
	    	//printf ("\nNo devices found with manufacturer \"anyma.ch\".\n\n");
    } else {
    	sleep(1);  // give some more time for USBasp to appear
    }
    	printf("--> Uploading\n");
    return 0;
}
Esempio n. 16
0
int main(int argc, char **argv)
{
usb_dev_handle      *handle = NULL;
const unsigned char rawVid[2] = {USB_CFG_VENDOR_ID}, rawPid[2] = {USB_CFG_DEVICE_ID};
char                vendor[] = {USB_CFG_VENDOR_NAME, 0}, product[] = {USB_CFG_DEVICE_NAME, 0};
char                buffer[4];
int                 cnt, vid, pid, isOn;

    usb_init();
    if(argc < 2){   /* we need at least one argument */
        usage(argv[0]);
        exit(1);
    }
    /* compute VID/PID from usbconfig.h so that there is a central source of information */
    vid = rawVid[1] * 256 + rawVid[0];
    pid = rawPid[1] * 256 + rawPid[0];
    /* The following function is in opendevice.c: */
    if(usbOpenDevice(&handle, vid, vendor, pid, product, NULL, NULL, NULL) != 0){
        fprintf(stderr, "Could not find USB device \"%s\" with vid=0x%x pid=0x%x\n", product, vid, pid);
        exit(1);
    }
    /* Since we use only control endpoint 0, we don't need to choose a
     * configuration and interface. Reading device descriptor and setting a
     * configuration and interface is done through endpoint 0 after all.
     * However, newer versions of Linux require that we claim an interface
     * even for endpoint 0. Enable the following code if your operating system
     * needs it: */
#if 0
    int retries = 1, usbConfiguration = 1, usbInterface = 0;
    if(usb_set_configuration(handle, usbConfiguration) && showWarnings){
        fprintf(stderr, "Warning: could not set configuration: %s\n", usb_strerror());
    }
    /* now try to claim the interface and detach the kernel HID driver on
     * Linux and other operating systems which support the call. */
    while((len = usb_claim_interface(handle, usbInterface)) != 0 && retries-- > 0){
#ifdef LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP
        if(usb_detach_kernel_driver_np(handle, 0) < 0 && showWarnings){
            fprintf(stderr, "Warning: could not detach kernel driver: %s\n", usb_strerror());
        }
#endif
    }
#endif

    if(strcasecmp(argv[1], "status") == 0){
        cnt = usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, CUSTOM_RQ_GET_STATUS, 0, 0, buffer, sizeof(buffer), 5000);
        if(cnt < 1){
            if(cnt < 0){
                fprintf(stderr, "USB error: %s\n", usb_strerror());
            }else{
                fprintf(stderr, "only %d bytes received.\n", cnt);
            }
        }else{
            printf("LED is %s\n", buffer[0] ? "on" : "off");
        }
    }else if((isOn = (strcasecmp(argv[1], "on") == 0)) || strcasecmp(argv[1], "off") == 0){
        cnt = usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_OUT, CUSTOM_RQ_SET_STATUS, isOn, 0, buffer, 0, 5000);
        if(cnt < 0){
            fprintf(stderr, "USB error: %s\n", usb_strerror());
        }
#if ENABLE_TEST
    }else if(strcasecmp(argv[1], "test") == 0){
        int i;
        srandomdev();
        for(i = 0; i < 50000; i++){
            int value = random() & 0xffff, index = random() & 0xffff;
            int rxValue, rxIndex;
            if((i+1) % 100 == 0){
                fprintf(stderr, "\r%05d", i+1);
                fflush(stderr);
            }
            cnt = usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, CUSTOM_RQ_ECHO, value, index, buffer, sizeof(buffer), 5000);
            if(cnt < 0){
                fprintf(stderr, "\nUSB error in iteration %d: %s\n", i, usb_strerror());
                break;
            }else if(cnt != 4){
                fprintf(stderr, "\nerror in iteration %d: %d bytes received instead of 4\n", i, cnt);
                break;
            }
            rxValue = ((int)buffer[0] & 0xff) | (((int)buffer[1] & 0xff) << 8);
            rxIndex = ((int)buffer[2] & 0xff) | (((int)buffer[3] & 0xff) << 8);
            if(rxValue != value || rxIndex != index){
                fprintf(stderr, "\ndata error in iteration %d:\n", i);
                fprintf(stderr, "rxValue = 0x%04x value = 0x%04x\n", rxValue, value);
                fprintf(stderr, "rxIndex = 0x%04x index = 0x%04x\n", rxIndex, index);
            }
        }
        fprintf(stderr, "\nTest completed.\n");
#endif /* ENABLE_TEST */
    }else{
        usage(argv[0]);
        exit(1);
    }
    usb_close(handle);
    return 0;
}
Esempio n. 17
0
static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hid_desc,
			   struct wacom_features *features)
{
	struct usb_device *dev = interface_to_usbdev(intf);
	char limit = 0;
	/* result has to be defined as int for some devices */
	int result = 0;
	int i = 0, usage = WCM_UNDEFINED, finger = 0, pen = 0;
	unsigned char *report;

	report = kzalloc(hid_desc->wDescriptorLength, GFP_KERNEL);
	if (!report)
		return -ENOMEM;

	/* retrive report descriptors */
	do {
		result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
			USB_REQ_GET_DESCRIPTOR,
			USB_RECIP_INTERFACE | USB_DIR_IN,
			HID_DEVICET_REPORT << 8,
			intf->altsetting[0].desc.bInterfaceNumber, /* interface */
			report,
			hid_desc->wDescriptorLength,
			5000); /* 5 secs */
	} while (result < 0 && limit++ < 5);

	/* No need to parse the Descriptor. It isn't an error though */
	if (result < 0)
		goto out;

	for (i = 0; i < hid_desc->wDescriptorLength; i++) {

		switch (report[i]) {
		case HID_USAGE_PAGE:
			switch (report[i + 1]) {
			case HID_USAGE_PAGE_DIGITIZER:
				usage = WCM_DIGITIZER;
				i++;
				break;

			case HID_USAGE_PAGE_DESKTOP:
				usage = WCM_DESKTOP;
				i++;
				break;
			}
			break;

		case HID_USAGE:
			switch (report[i + 1]) {
			case HID_USAGE_X:
				if (usage == WCM_DESKTOP) {
					if (finger) {
						features->device_type = BTN_TOOL_DOUBLETAP;
						if (features->type == TABLETPC2FG) {
							/* need to reset back */
							features->pktlen = WACOM_PKGLEN_TPC2FG;
							features->device_type = BTN_TOOL_TRIPLETAP;
						}
						features->x_max =
							wacom_le16_to_cpu(&report[i + 3]);
						features->x_phy =
							wacom_le16_to_cpu(&report[i + 6]);
						features->unit = report[i + 9];
						features->unitExpo = report[i + 11];
						i += 12;
					} else if (pen) {
						/* penabled only accepts exact bytes of data */
						if (features->type == TABLETPC2FG)
							features->pktlen = WACOM_PKGLEN_GRAPHIRE;
						features->device_type = BTN_TOOL_PEN;
						features->x_max =
							wacom_le16_to_cpu(&report[i + 3]);
						i += 4;
					}
				} else if (usage == WCM_DIGITIZER) {
					/* max pressure isn't reported
					features->pressure_max = (unsigned short)
							(report[i+4] << 8  | report[i + 3]);
					*/
					features->pressure_max = 255;
					i += 4;
				}
				break;

			case HID_USAGE_Y:
				if (usage == WCM_DESKTOP) {
					if (finger) {
						features->device_type = BTN_TOOL_DOUBLETAP;
						if (features->type == TABLETPC2FG) {
							/* need to reset back */
							features->pktlen = WACOM_PKGLEN_TPC2FG;
							features->device_type = BTN_TOOL_TRIPLETAP;
							features->y_max =
								wacom_le16_to_cpu(&report[i + 3]);
							features->y_phy =
								wacom_le16_to_cpu(&report[i + 6]);
							i += 7;
						} else {
							features->y_max =
								features->x_max;
							features->y_phy =
								wacom_le16_to_cpu(&report[i + 3]);
							i += 4;
						}
					} else if (pen) {
						/* penabled only accepts exact bytes of data */
						if (features->type == TABLETPC2FG)
							features->pktlen = WACOM_PKGLEN_GRAPHIRE;
						features->device_type = BTN_TOOL_PEN;
						features->y_max =
							wacom_le16_to_cpu(&report[i + 3]);
						i += 4;
					}
				}
				break;

			case HID_USAGE_FINGER:
				finger = 1;
				i++;
				break;

			case HID_USAGE_STYLUS:
				pen = 1;
				i++;
				break;

			case HID_USAGE_UNDEFINED:
				if (usage == WCM_DESKTOP && finger) /* capacity */
					features->pressure_max =
						wacom_le16_to_cpu(&report[i + 3]);
				i += 4;
				break;
			}
			break;

		case HID_COLLECTION:
			/* reset UsagePage and Finger */
			finger = usage = 0;
			break;
		}
	}

 out:
	result = 0;
	kfree(report);
	return result;
}
static int
pnwotg_test_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
	struct pnwotg_test_dev	*dev;
	int retval, portNum;

	dev_dbg(&intf->dev, "Penwell OTG test mode is initiated.\n");
	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
	if (!dev)
		return -ENOMEM;

	dev->buf = kmalloc(TBUF_SIZE, GFP_KERNEL);
	if (!dev->buf) {
		kfree(dev);
		return -ENOMEM;
	}

	dev->udev = usb_get_dev(interface_to_usbdev(intf));
	dev->hcd = usb_get_hcd(bus_to_hcd(dev->udev->bus));
	usb_set_intfdata(intf, dev);
	portNum = dev->udev->portnum & 0xff;

	dev_dbg(&intf->dev, "test mode PID 0x%04x\n",
		le16_to_cpu(dev->udev->descriptor.idProduct));
	switch (le16_to_cpu(dev->udev->descriptor.idProduct)) {
	case 0x0101:
		/* TEST_SE0_NAK */
		dev->hcd->driver->hub_control(dev->hcd, SetPortFeature,
			USB_PORT_FEAT_TEST, 0x300 + portNum, NULL, 0);
		break;
	case 0x0102:
		/* TEST_J */
		dev->hcd->driver->hub_control(dev->hcd, SetPortFeature,
			USB_PORT_FEAT_TEST, 0x100 + portNum, NULL, 0);
		break;
	case 0x0103:
		/* TEST_K */
		dev->hcd->driver->hub_control(dev->hcd, SetPortFeature,
			USB_PORT_FEAT_TEST, 0x200 + portNum, NULL, 0);
		break;
	case 0x0104:
		/* TEST_PACKET */
		dev->hcd->driver->hub_control(dev->hcd, SetPortFeature,
			USB_PORT_FEAT_TEST, 0x400 + portNum, NULL, 0);
		break;
	case 0x0106:
		/* HS_HOST_PORT_SUSPEND_RESUME */
		msleep(15000);
		dev->hcd->driver->hub_control(dev->hcd, SetPortFeature,
			USB_PORT_FEAT_SUSPEND, portNum, NULL, 0);
		msleep(15000);
		dev->hcd->driver->hub_control(dev->hcd, ClearPortFeature,
			USB_PORT_FEAT_SUSPEND, portNum, NULL, 0);
		break;
	case 0x0107:
		/* SINGLE_STEP_GET_DEV_DESC */
		msleep(15000);
		retval = usb_control_msg(dev->udev,
				usb_rcvctrlpipe(dev->udev, 0),
				USB_REQ_GET_DESCRIPTOR,
				USB_DIR_IN | USB_RECIP_DEVICE,
				cpu_to_le16(USB_DT_DEVICE << 8),
				0, dev->buf,
				USB_DT_DEVICE_SIZE,
				USB_CTRL_GET_TIMEOUT);
		break;
	case 0x0108:
		/* SINGLE_STEP_SET_FEATURE */

		/* FIXME */
		/* set size = 0 to ignore DATA phase */
		retval = usb_control_msg(dev->udev,
				usb_rcvctrlpipe(dev->udev, 0),
				USB_REQ_GET_DESCRIPTOR,
				USB_DIR_IN | USB_RECIP_DEVICE,
				cpu_to_le16(USB_DT_DEVICE << 8),
				0, dev->buf, 0,
				USB_CTRL_GET_TIMEOUT);
		msleep(15000);
		retval = usb_control_msg(dev->udev,
				usb_rcvctrlpipe(dev->udev, 0),
				USB_REQ_GET_DESCRIPTOR,
				USB_DIR_IN | USB_RECIP_DEVICE,
				cpu_to_le16(USB_DT_DEVICE << 8),
				0, dev->buf,
				USB_DT_DEVICE_SIZE,
				USB_CTRL_GET_TIMEOUT);
		break;
	default:
		dev_info(&intf->dev, "unknown test mode with PID 0x%04x",
			id->idProduct);
		usb_notify_warning(dev->udev, USB_WARNING_NOT_SUPPORT);
	}

	return 0;
}
		printk(KERN_DEBUG "(dev %p, pipe %08x): ", dev->udev, pipe);

		printk(KERN_CONT "%s: %02x %02x %02x %02x %02x %02x %02x %02x ",
			(req_type & USB_DIR_IN) ? " IN" : "OUT",
			req_type, req, value&0xff, value>>8, index&0xff,
			index>>8, len&0xff, len>>8);

		if (!(req_type & USB_DIR_IN)) {
			printk(KERN_CONT ">>> ");
			for (i = 0; i < len; i++)
				printk(KERN_CONT " %02x", buf[i]);
			printk(KERN_CONT "\n");
		}
	}

	ret = usb_control_msg(dev->udev, pipe, req, req_type, value, index,
			      data, len, USB_TIMEOUT);

	if (req_type &  USB_DIR_IN)
		memcpy(buf, data, len);

	if (tm6000_debug & V4L2_DEBUG_I2C) {
		if (ret < 0) {
			if (req_type &  USB_DIR_IN)
				printk(KERN_DEBUG "<<< (len=%d)\n", len);

			printk(KERN_CONT "%s: Error #%d\n", __func__, ret);
		} else if (req_type &  USB_DIR_IN) {
			printk(KERN_CONT "<<< ");
			for (i = 0; i < len; i++)
				printk(KERN_CONT " %02x", buf[i]);
			printk(KERN_CONT "\n");
/**ltl
功能:设置当前接口
参数:
返回值:
*/
int usb_set_interface(struct usb_device *dev, int interface, int alternate)
{
	struct usb_interface *iface;
	struct usb_host_interface *alt;
	int ret;
	int manual = 0;

	if (dev->state == USB_STATE_SUSPENDED)
		return -EHOSTUNREACH;

	iface = usb_ifnum_to_if(dev, interface);
	if (!iface) {
		dev_dbg(&dev->dev, "selecting invalid interface %d\n",
			interface);
		return -EINVAL;
	}

	alt = usb_altnum_to_altsetting(iface, alternate);
	if (!alt) {
		warn("selecting invalid altsetting %d", alternate);
		return -EINVAL;
	}

	ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
				   USB_REQ_SET_INTERFACE, USB_RECIP_INTERFACE,
				   alternate, interface, NULL, 0, 5000);

	/* 9.4.10 says devices don't need this and are free to STALL the
	 * request if the interface only has one alternate setting.
	 */
	if (ret == -EPIPE && iface->num_altsetting == 1) {
		dev_dbg(&dev->dev,
			"manual set_interface for iface %d, alt %d\n",
			interface, alternate);
		manual = 1;
	} else if (ret < 0)
		return ret;

	/* FIXME drivers shouldn't need to replicate/bugfix the logic here
	 * when they implement async or easily-killable versions of this or
	 * other "should-be-internal" functions (like clear_halt).
	 * should hcd+usbcore postprocess control requests?
	 */

	/* prevent submissions using previous endpoint settings */
	if (device_is_registered(&iface->dev))
		usb_remove_sysfs_intf_files(iface);
	usb_disable_interface(dev, iface);

	iface->cur_altsetting = alt;

	/* If the interface only has one altsetting and the device didn't
	 * accept the request, we attempt to carry out the equivalent action
	 * by manually clearing the HALT feature for each endpoint in the
	 * new altsetting.
	 */
	if (manual) {
		int i;

		for (i = 0; i < alt->desc.bNumEndpoints; i++) {
			unsigned int epaddr =
				alt->endpoint[i].desc.bEndpointAddress;
			unsigned int pipe =
	__create_pipe(dev, USB_ENDPOINT_NUMBER_MASK & epaddr)
	| (usb_endpoint_out(epaddr) ? USB_DIR_OUT : USB_DIR_IN);

			usb_clear_halt(dev, pipe);
		}
	}

	/* 9.1.1.5: reset toggles for all endpoints in the new altsetting
	 *
	 * Note:
	 * Despite EP0 is always present in all interfaces/AS, the list of
	 * endpoints from the descriptor does not contain EP0. Due to its
	 * omnipresence one might expect EP0 being considered "affected" by
	 * any SetInterface request and hence assume toggles need to be reset.
	 * However, EP0 toggles are re-synced for every individual transfer
	 * during the SETUP stage - hence EP0 toggles are "don't care" here.
	 * (Likewise, EP0 never "halts" on well designed devices.)
	 */
	usb_enable_interface(dev, iface);
	if (device_is_registered(&iface->dev))
		usb_create_sysfs_intf_files(iface);

	return 0;
}
Esempio n. 21
0
/* FIXME: split and cleanup */
int wusb_dev_4way_handshake(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev,
			    struct wusb_ckhdid *ck)
{
	int result = -ENOMEM;
	struct usb_device *usb_dev = wusb_dev->usb_dev;
	struct device *dev = &usb_dev->dev;
	u32 tkid;
	__le32 tkid_le;
	struct usb_handshake *hs;
	struct aes_ccm_nonce ccm_n;
	u8 mic[8];
	struct wusb_keydvt_in keydvt_in;
	struct wusb_keydvt_out keydvt_out;

	hs = kzalloc(3*sizeof(hs[0]), GFP_KERNEL);
	if (hs == NULL) {
		dev_err(dev, "can't allocate handshake data\n");
		goto error_kzalloc;
	}

	/* We need to turn encryption before beginning the 4way
	 * hshake (WUSB1.0[.3.2.2]) */
	result = wusb_dev_set_encryption(usb_dev, 1);
	if (result < 0)
		goto error_dev_set_encryption;

	tkid = wusbhc_next_tkid(wusbhc, wusb_dev);
	tkid_le = cpu_to_le32(tkid);

	hs[0].bMessageNumber = 1;
	hs[0].bStatus = 0;
	memcpy(hs[0].tTKID, &tkid_le, sizeof(hs[0].tTKID));
	hs[0].bReserved = 0;
	memcpy(hs[0].CDID, &wusb_dev->cdid, sizeof(hs[0].CDID));
	get_random_bytes(&hs[0].nonce, sizeof(hs[0].nonce));
	memset(hs[0].MIC, 0, sizeof(hs[0].MIC));	/* Per WUSB1.0[T7-22] */

	result = usb_control_msg(
		usb_dev, usb_sndctrlpipe(usb_dev, 0),
		USB_REQ_SET_HANDSHAKE,
		USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE,
		1, 0, &hs[0], sizeof(hs[0]), 1000 /* FIXME: arbitrary */);
	if (result < 0) {
		dev_err(dev, "Handshake1: request failed: %d\n", result);
		goto error_hs1;
	}

	/* Handshake 2, from the device -- need to verify fields */
	result = usb_control_msg(
		usb_dev, usb_rcvctrlpipe(usb_dev, 0),
		USB_REQ_GET_HANDSHAKE,
		USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE,
		2, 0, &hs[1], sizeof(hs[1]), 1000 /* FIXME: arbitrary */);
	if (result < 0) {
		dev_err(dev, "Handshake2: request failed: %d\n", result);
		goto error_hs2;
	}

	result = -EINVAL;
	if (hs[1].bMessageNumber != 2) {
		dev_err(dev, "Handshake2 failed: bad message number %u\n",
			hs[1].bMessageNumber);
		goto error_hs2;
	}
	if (hs[1].bStatus != 0) {
		dev_err(dev, "Handshake2 failed: bad status %u\n",
			hs[1].bStatus);
		goto error_hs2;
	}
	if (memcmp(hs[0].tTKID, hs[1].tTKID, sizeof(hs[0].tTKID))) {
		dev_err(dev, "Handshake2 failed: TKID mismatch "
			"(#1 0x%02x%02x%02x vs #2 0x%02x%02x%02x)\n",
			hs[0].tTKID[0], hs[0].tTKID[1], hs[0].tTKID[2],
			hs[1].tTKID[0], hs[1].tTKID[1], hs[1].tTKID[2]);
		goto error_hs2;
	}
	if (memcmp(hs[0].CDID, hs[1].CDID, sizeof(hs[0].CDID))) {
		dev_err(dev, "Handshake2 failed: CDID mismatch\n");
		goto error_hs2;
	}

	/* Setup the CCM nonce */
	memset(&ccm_n.sfn, 0, sizeof(ccm_n.sfn));	/* Per WUSB1.0[6.5.2] */
	memcpy(ccm_n.tkid, &tkid_le, sizeof(ccm_n.tkid));
	ccm_n.src_addr = wusbhc->uwb_rc->uwb_dev.dev_addr;
	ccm_n.dest_addr.data[0] = wusb_dev->addr;
	ccm_n.dest_addr.data[1] = 0;

	/* Derive the KCK and PTK from CK, the CCM, H and D nonces */
	memcpy(keydvt_in.hnonce, hs[0].nonce, sizeof(keydvt_in.hnonce));
	memcpy(keydvt_in.dnonce, hs[1].nonce, sizeof(keydvt_in.dnonce));
	result = wusb_key_derive(&keydvt_out, ck->data, &ccm_n, &keydvt_in);
	if (result < 0) {
		dev_err(dev, "Handshake2 failed: cannot derive keys: %d\n",
			result);
		goto error_hs2;
	}

	/* Compute MIC and verify it */
	result = wusb_oob_mic(mic, keydvt_out.kck, &ccm_n, &hs[1]);
	if (result < 0) {
		dev_err(dev, "Handshake2 failed: cannot compute MIC: %d\n",
			result);
		goto error_hs2;
	}

	if (memcmp(hs[1].MIC, mic, sizeof(hs[1].MIC))) {
		dev_err(dev, "Handshake2 failed: MIC mismatch\n");
		goto error_hs2;
	}

	/* Send Handshake3 */
	hs[2].bMessageNumber = 3;
	hs[2].bStatus = 0;
	memcpy(hs[2].tTKID, &tkid_le, sizeof(hs[2].tTKID));
	hs[2].bReserved = 0;
	memcpy(hs[2].CDID, &wusb_dev->cdid, sizeof(hs[2].CDID));
	memcpy(hs[2].nonce, hs[0].nonce, sizeof(hs[2].nonce));
	result = wusb_oob_mic(hs[2].MIC, keydvt_out.kck, &ccm_n, &hs[2]);
	if (result < 0) {
		dev_err(dev, "Handshake3 failed: cannot compute MIC: %d\n",
			result);
		goto error_hs2;
	}

	result = usb_control_msg(
		usb_dev, usb_sndctrlpipe(usb_dev, 0),
		USB_REQ_SET_HANDSHAKE,
		USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE,
		3, 0, &hs[2], sizeof(hs[2]), 1000 /* FIXME: arbitrary */);
	if (result < 0) {
		dev_err(dev, "Handshake3: request failed: %d\n", result);
		goto error_hs3;
	}

	result = wusbhc->set_ptk(wusbhc, wusb_dev->port_idx, tkid,
				 keydvt_out.ptk, sizeof(keydvt_out.ptk));
	if (result < 0)
		goto error_wusbhc_set_ptk;

	result = wusb_dev_set_gtk(wusbhc, wusb_dev);
	if (result < 0) {
		dev_err(dev, "Set GTK for device: request failed: %d\n",
			result);
		goto error_wusbhc_set_gtk;
	}

	/* Update the device's address from unauth to auth */
	if (usb_dev->authenticated == 0) {
		result = wusb_dev_update_address(wusbhc, wusb_dev);
		if (result < 0)
			goto error_dev_update_address;
	}
	result = 0;
	dev_info(dev, "device authenticated\n");

error_dev_update_address:
error_wusbhc_set_gtk:
error_wusbhc_set_ptk:
error_hs3:
error_hs2:
error_hs1:
	memset(hs, 0, 3*sizeof(hs[0]));
	memset(&keydvt_out, 0, sizeof(keydvt_out));
	memset(&keydvt_in, 0, sizeof(keydvt_in));
	memset(&ccm_n, 0, sizeof(ccm_n));
	memset(mic, 0, sizeof(mic));
	if (result < 0)
		wusb_dev_set_encryption(usb_dev, 0);
error_dev_set_encryption:
	kfree(hs);
error_kzalloc:
	return result;
}
/**ltl
功能:设置usb设备的配置,并且加载与接口相关的驱动程序
参数:dev			->usb设备
	configuration	->usb配置编号
返回值:
说明:调用这个接口,usb设备才会进入配置阶段
*/
int usb_set_configuration(struct usb_device *dev, int configuration)
{
	int i, ret;
	struct usb_host_config *cp = NULL;
	struct usb_interface **new_interfaces = NULL;
	int n, nintf;

	for (i = 0; i < dev->descriptor.bNumConfigurations; i++) {
		if (dev->config[i].desc.bConfigurationValue == configuration) {
			cp = &dev->config[i];
			break;
		}
	}
	if ((!cp && configuration != 0))
		return -EINVAL;

	/* The USB spec says configuration 0 means unconfigured.
	 * But if a device includes a configuration numbered 0,
	 * we will accept it as a correctly configured state.
	 */
	if (cp && configuration == 0)
		dev_warn(&dev->dev, "config 0 descriptor??\n");

	if (dev->state == USB_STATE_SUSPENDED)
		return -EHOSTUNREACH;

	/* Allocate memory for new interfaces before doing anything else,
	 * so that if we run out then nothing will have changed. */
	n = nintf = 0;
	if (cp) {
		nintf = cp->desc.bNumInterfaces;//接口数量
		new_interfaces = kmalloc(nintf * sizeof(*new_interfaces),
				GFP_KERNEL);
		if (!new_interfaces) {
			dev_err(&dev->dev, "Out of memory");
			return -ENOMEM;
		}

		for (; n < nintf; ++n) {
			new_interfaces[n] = kzalloc(
					sizeof(struct usb_interface),
					GFP_KERNEL);
			if (!new_interfaces[n]) {
				dev_err(&dev->dev, "Out of memory");
				ret = -ENOMEM;
free_interfaces:
				while (--n >= 0)
					kfree(new_interfaces[n]);
				kfree(new_interfaces);
				return ret;
			}
		}

		i = dev->bus_mA - cp->desc.bMaxPower * 2;
		if (i < 0)
			dev_warn(&dev->dev, "new config #%d exceeds power "
					"limit by %dmA\n",
					configuration, -i);
	}

	/* if it's already configured, clear out old state first.
	 * getting rid of old interfaces means unbinding their drivers.
	 */
	if (dev->state != USB_STATE_ADDRESS)
		usb_disable_device (dev, 1);	// Skip ep0

	//设置配置编号
	if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
			USB_REQ_SET_CONFIGURATION, 0, configuration, 0,
			NULL, 0, USB_CTRL_SET_TIMEOUT)) < 0) {

		/* All the old state is gone, so what else can we do?
		 * The device is probably useless now anyway.
		 */
		cp = NULL;
	}
	//当前的配置对象
	dev->actconfig = cp;
	if (!cp) {
		usb_set_device_state(dev, USB_STATE_ADDRESS);
		goto free_interfaces;
	}
	usb_set_device_state(dev, USB_STATE_CONFIGURED);

	/* Initialize the new interface structures and the
	 * hc/hcd/usbcore interface/endpoint state.
	 */
	//对interface对象赋值
	for (i = 0; i < nintf; ++i) {
		struct usb_interface_cache *intfc;
		struct usb_interface *intf;
		struct usb_host_interface *alt;

		cp->interface[i] = intf = new_interfaces[i];
		intfc = cp->intf_cache[i];
		intf->altsetting = intfc->altsetting;
		intf->num_altsetting = intfc->num_altsetting;
		kref_get(&intfc->ref);

		alt = usb_altnum_to_altsetting(intf, 0);

		/* No altsetting 0?  We'll assume the first altsetting.
		 * We could use a GetInterface call, but if a device is
		 * so non-compliant that it doesn't have altsetting 0
		 * then I wouldn't trust its reply anyway.
		 */
		if (!alt)
			alt = &intf->altsetting[0];

		intf->cur_altsetting = alt;
		usb_enable_interface(dev, intf);
		intf->dev.parent = &dev->dev;
		intf->dev.driver = NULL;
		/*总线驱动模型中,interface作为设备,如果interface是一个usb hub(bInterfaceClass=9),则按总线驱动模型,就会匹配hub_driver驱动,调用device_add后,
		  最后调用hub_probe,去 分配usb_hub对象,并为每个hub关联中断处理函数,当hub端口中有设备插入时,hub产生
		  一中断hub_irq,最终唤醒线程hub_thread,然后为usb设备分配设备号(hub_port_connect_change)
		  ;如果interface是一个usb设备(bInterfaceClass=x),比如:usbmouse,此时会去匹配usb_mouse_driver。	
		*/
		intf->dev.bus = &usb_bus_type;
		intf->dev.dma_mask = dev->dev.dma_mask;
		intf->dev.release = release_interface;
		device_initialize (&intf->dev);
		mark_quiesced(intf);
		sprintf (&intf->dev.bus_id[0], "%d-%s:%d.%d",
			 dev->bus->busnum, dev->devpath,
			 configuration, alt->desc.bInterfaceNumber);
	}
	kfree(new_interfaces);

	if (cp->string == NULL)
		cp->string = usb_cache_string(dev, cp->desc.iConfiguration);

	/* Now that all the interfaces are set up, register them
	 * to trigger binding of drivers to interfaces.  probe()
	 * routines may install different altsettings and may
	 * claim() any interfaces not yet bound.  Many class drivers
	 * need that: CDC, audio, video, etc.
	 */
	/*每个接口代表一个功能,每个接口都有一个驱动程序,载之*/
	for (i = 0; i < nintf; ++i) {
		struct usb_interface *intf = cp->interface[i];

		dev_dbg (&dev->dev,
			"adding %s (config #%d, interface %d)\n",
			intf->dev.bus_id, configuration,
			intf->cur_altsetting->desc.bInterfaceNumber);
		//执行后,设备驱动将执行探针接口:hub_probe,storage_probe
		ret = device_add (&intf->dev);
		if (ret != 0) {
			dev_err(&dev->dev, "device_add(%s) --> %d\n",
				intf->dev.bus_id, ret);
			continue;
		}
		usb_create_sysfs_intf_files (intf);
	}

	return 0;
}
Esempio n. 23
0
static int  kobil_tiocmset(struct usb_serial_port *port, struct file *file,
			   unsigned int set, unsigned int clear)
{
	struct kobil_private * priv;
	int result;
	int dtr = 0;
	int rts = 0;
	unsigned char *transfer_buffer;
	int transfer_buffer_length = 8;

	priv = usb_get_serial_port_data(port);
	if ((priv->device_type == KOBIL_USBTWIN_PRODUCT_ID) || (priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID)) {
		// This device doesn't support ioctl calls
		return -EINVAL;
	}

	// allocate memory for transfer buffer
	transfer_buffer = kzalloc(transfer_buffer_length, GFP_KERNEL);
	if (! transfer_buffer) {
		return -ENOMEM;
	}

	if (set & TIOCM_RTS)
		rts = 1;
	if (set & TIOCM_DTR)
		dtr = 1;
	if (clear & TIOCM_RTS)
		rts = 0;
	if (clear & TIOCM_DTR)
		dtr = 0;

	if (priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID) {
		if (dtr != 0)
			dbg("%s - port %d Setting DTR", __FUNCTION__, port->number);
		else
			dbg("%s - port %d Clearing DTR", __FUNCTION__, port->number);
		result = usb_control_msg( port->serial->dev, 
					  usb_rcvctrlpipe(port->serial->dev, 0 ), 
					  SUSBCRequest_SetStatusLinesOrQueues,
					  USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT,
					  ((dtr != 0) ? SUSBCR_SSL_SETDTR : SUSBCR_SSL_CLRDTR),
					  0,
					  transfer_buffer,
					  0,
					  KOBIL_TIMEOUT);
	} else {
		if (rts != 0)
			dbg("%s - port %d Setting RTS", __FUNCTION__, port->number);
		else
			dbg("%s - port %d Clearing RTS", __FUNCTION__, port->number);
		result = usb_control_msg( port->serial->dev, 
					  usb_rcvctrlpipe(port->serial->dev, 0 ), 
					  SUSBCRequest_SetStatusLinesOrQueues,
					  USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT,
					  ((rts != 0) ? SUSBCR_SSL_SETRTS : SUSBCR_SSL_CLRRTS),
					  0,
					  transfer_buffer,
					  0,
					  KOBIL_TIMEOUT);
	}
	dbg("%s - port %d Send set_status_line URB returns: %i", __FUNCTION__, port->number, result);
	kfree(transfer_buffer);
	return (result < 0) ? result : 0;
}
/*
 * RPC done RNDIS-style.  Caller guarantees:
 * - message is properly byteswapped
 * - there's no other request pending
 * - buf can hold up to 1KB response (required by RNDIS spec)
 * On return, the first few entries are already byteswapped.
 *
 * Call context is likely probe(), before interface name is known,
 * which is why we won't try to use it in the diagnostics.
 */
int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf, int buflen)
{
	struct cdc_state	*info = (void *) &dev->data;
	struct usb_cdc_notification notification;
	int			master_ifnum;
	int			retval;
	int			partial;
	unsigned		count;
	__le32			rsp;
	u32			xid = 0, msg_len, request_id;

	/* REVISIT when this gets called from contexts other than probe() or
	 * disconnect(): either serialize, or dispatch responses on xid
	 */

	/* Issue the request; xid is unique, don't bother byteswapping it */
	if (likely(buf->msg_type != RNDIS_MSG_HALT &&
		   buf->msg_type != RNDIS_MSG_RESET)) {
		xid = dev->xid++;
		if (!xid)
			xid = dev->xid++;
		buf->request_id = (__force __le32) xid;
	}
	master_ifnum = info->control->cur_altsetting->desc.bInterfaceNumber;
	retval = usb_control_msg(dev->udev,
		usb_sndctrlpipe(dev->udev, 0),
		USB_CDC_SEND_ENCAPSULATED_COMMAND,
		USB_TYPE_CLASS | USB_RECIP_INTERFACE,
		0, master_ifnum,
		buf, le32_to_cpu(buf->msg_len),
		RNDIS_CONTROL_TIMEOUT_MS);
	if (unlikely(retval < 0 || xid == 0))
		return retval;

	/* Some devices don't respond on the control channel until
	 * polled on the status channel, so do that first. */
	retval = usb_interrupt_msg(
		dev->udev,
		usb_rcvintpipe(dev->udev, dev->status->desc.bEndpointAddress),
		&notification, sizeof(notification), &partial,
		RNDIS_CONTROL_TIMEOUT_MS);
	if (unlikely(retval < 0))
		return retval;

	/* Poll the control channel; the request probably completed immediately */
	rsp = buf->msg_type | RNDIS_MSG_COMPLETION;
	for (count = 0; count < 10; count++) {
		memset(buf, 0, CONTROL_BUFFER_SIZE);
		retval = usb_control_msg(dev->udev,
			usb_rcvctrlpipe(dev->udev, 0),
			USB_CDC_GET_ENCAPSULATED_RESPONSE,
			USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
			0, master_ifnum,
			buf, buflen,
			RNDIS_CONTROL_TIMEOUT_MS);
		if (likely(retval >= 8)) {
			msg_len = le32_to_cpu(buf->msg_len);
			request_id = (__force u32) buf->request_id;
			if (likely(buf->msg_type == rsp)) {
				if (likely(request_id == xid)) {
					if (unlikely(rsp == RNDIS_MSG_RESET_C))
						return 0;
					if (likely(RNDIS_STATUS_SUCCESS
							== buf->status))
						return 0;
					dev_dbg(&info->control->dev,
						"rndis reply status %08x\n",
						le32_to_cpu(buf->status));
					return -EL3RST;
				}
				dev_dbg(&info->control->dev,
					"rndis reply id %d expected %d\n",
					request_id, xid);
				/* then likely retry */
			} else switch (buf->msg_type) {
			case RNDIS_MSG_INDICATE:	/* fault/event */
				rndis_msg_indicate(dev, (void *)buf, buflen);

				break;
			case RNDIS_MSG_KEEPALIVE: {	/* ping */
				struct rndis_keepalive_c *msg = (void *)buf;

				msg->msg_type = RNDIS_MSG_KEEPALIVE_C;
				msg->msg_len = cpu_to_le32(sizeof *msg);
				msg->status = RNDIS_STATUS_SUCCESS;
				retval = usb_control_msg(dev->udev,
					usb_sndctrlpipe(dev->udev, 0),
					USB_CDC_SEND_ENCAPSULATED_COMMAND,
					USB_TYPE_CLASS | USB_RECIP_INTERFACE,
					0, master_ifnum,
					msg, sizeof *msg,
					RNDIS_CONTROL_TIMEOUT_MS);
				if (unlikely(retval < 0))
					dev_dbg(&info->control->dev,
						"rndis keepalive err %d\n",
						retval);
				}
				break;
			default:
				dev_dbg(&info->control->dev,
					"unexpected rndis msg %08x len %d\n",
					le32_to_cpu(buf->msg_type), msg_len);
			}
		} else {
			/* device probably issued a protocol stall; ignore */
			dev_dbg(&info->control->dev,
				"rndis response error, code %d\n", retval);
		}
		msleep(20);
	}
	dev_dbg(&info->control->dev, "rndis response timeout\n");
	return -ETIMEDOUT;
}
Esempio n. 25
0
/* Probe if this driver wants to serve an USB device

   This entry point is called whenever a new device is attached to the bus.
   Then the device driver has to create a new instance of its internal data
   structures for the new device.

   The  dev argument specifies the device context, which contains pointers
   to all USB descriptors. The  interface argument specifies the interface
   number. If a USB driver wants to bind itself to a particular device and
   interface it has to return a pointer. This pointer normally references
   the device driver's context structure.

   Probing normally is done by checking the vendor and product identifications
   or the class and subclass definitions. If they match the interface number
   is compared with the ones supported by the driver. When probing is done
   class based it might be necessary to parse some more USB descriptors because
   the device properties can differ in a wide range.
*/
static void *auerswald_probe(struct usb_device *usbdev, unsigned int ifnum,
			     const struct usb_device_id *id)
{
	struct auerswald *cp = NULL;
	DECLARE_WAIT_QUEUE_HEAD(wqh);
	unsigned int dtindex;
	unsigned int u = 0;
	char *pbuf;
	int ret;

	dbg("probe: vendor id 0x%x, device id 0x%x ifnum:%d",
	    usbdev->descriptor.idVendor, usbdev->descriptor.idProduct,
	    ifnum);

	/* See if the device offered us matches that we can accept */
	if (usbdev->descriptor.idVendor != ID_AUERSWALD)
		return NULL;

	/* we use only the first -and only- interface */
	if (ifnum != 0)
		return NULL;

	/* prevent module unloading while sleeping */
	MOD_INC_USE_COUNT;

	/* allocate memory for our device and intialize it */
	cp = kmalloc(sizeof(struct auerswald), GFP_KERNEL);
	if (cp == NULL) {
		err("out of memory");
		goto pfail;
	}

	/* Initialize device descriptor */
	memset(cp, 0, sizeof(struct auerswald));
	init_MUTEX(&cp->mutex);
	cp->usbdev = usbdev;
	auerchain_init(&cp->controlchain);
	auerbuf_init(&cp->bufctl);
	init_waitqueue_head(&cp->bufferwait);
	auerisdn_init_dev(cp);

	/* find a free slot in the device table */
	down(&auerdev_table_mutex);
	for (dtindex = 0; dtindex < AUER_MAX_DEVICES; ++dtindex) {
		if (auerdev_table[dtindex] == NULL)
			break;
	}
	if (dtindex >= AUER_MAX_DEVICES) {
		err("more than %d devices plugged in, can not handle this device", AUER_MAX_DEVICES);
		up(&auerdev_table_mutex);
		goto pfail;
	}

	/* Give the device a name */
	sprintf(cp->name, AU_PREFIX "%d", dtindex);

	/* Store the index */
	cp->dtindex = dtindex;
	auerdev_table[dtindex] = cp;
	up(&auerdev_table_mutex);

	/* initialize the devfs node for this device and register it */
	cp->devfs = devfs_register(usb_devfs_handle, cp->name,
				   DEVFS_FL_DEFAULT, USB_MAJOR,
				   AUER_MINOR_BASE + dtindex,
				   S_IFCHR | S_IRUGO | S_IWUGO,
				   &auerswald_fops, NULL);

	/* Get the usb version of the device */
	cp->version = cp->usbdev->descriptor.bcdDevice;
	dbg("Version is %X", cp->version);

	/* allow some time to settle the device */
	sleep_on_timeout(&wqh, HZ / 3);

	/* Try to get a suitable textual description of the device */
	/* Device name: */
	ret =
	    usb_string(cp->usbdev, AUSI_DEVICE, cp->dev_desc,
		       AUSI_DLEN - 1);
	if (ret >= 0) {
		u += ret;
		/* Append Serial Number */
		memcpy(&cp->dev_desc[u], ",Ser# ", 6);
		u += 6;
		ret =
		    usb_string(cp->usbdev, AUSI_SERIALNR, &cp->dev_desc[u],
			       AUSI_DLEN - u - 1);
		if (ret >= 0) {
			u += ret;
			/* Append subscriber number */
			memcpy(&cp->dev_desc[u], ", ", 2);
			u += 2;
			ret =
			    usb_string(cp->usbdev, AUSI_MSN,
				       &cp->dev_desc[u],
				       AUSI_DLEN - u - 1);
			if (ret >= 0) {
				u += ret;
			}
		}
	}
	cp->dev_desc[u] = '\0';
	info("device is a %s", cp->dev_desc);

	/* get the maximum allowed control transfer length */
	pbuf = (char *) kmalloc(2, GFP_KERNEL);	/* use an allocated buffer because of urb target */
	if (!pbuf) {
		err("out of memory");
		goto pfail;
	}
	ret = usb_control_msg(cp->usbdev,			/* pointer to device */
			      usb_rcvctrlpipe(cp->usbdev, 0),	/* pipe to control endpoint */
			      AUV_GETINFO,			/* USB message request value */
			      AUT_RREQ,				/* USB message request type value */
			      0,				/* USB message value */
			      AUDI_MBCTRANS,			/* USB message index value */
			      pbuf,				/* pointer to the receive buffer */
			      2,				/* length of the buffer */
			      HZ * 2);				/* time to wait for the message to complete before timing out */
	if (ret == 2) {
		cp->maxControlLength = le16_to_cpup(pbuf);
		kfree(pbuf);
		dbg("setup: max. allowed control transfersize is %d bytes",
		    cp->maxControlLength);
	} else {
		kfree(pbuf);
		err("setup: getting max. allowed control transfer length failed with error %d", ret);
		goto pfail;
	}
	/* allocate a chain for the control messages */
	if (auerchain_setup(&cp->controlchain, AUCH_ELEMENTS)) {
		err("out of memory");
		goto pfail;
	}

	/* allocate buffers for control messages */
	if (auerbuf_setup
	    (&cp->bufctl, AU_RBUFFERS * 2,
	     cp->maxControlLength + AUH_SIZE)) {
		err("out of memory");
		goto pfail;
	}

	/* start the interrupt endpoint */
	if (auerswald_int_open(cp)) {
		err("int endpoint failed");
		goto pfail;
	}

	/* Try to connect to hisax interface */
	if (auerisdn_probe(cp)) {
		err("hisax connect failed");
		goto pfail;
	}

	/* all OK */
	return cp;

	/* Error exit: clean up the memory */
      pfail:auerswald_delete(cp);
	MOD_DEC_USE_COUNT;
	return NULL;
}
Esempio n. 26
0
int main(int argc, char **argv)
{
usb_dev_handle      *handle;
unsigned char       buffer[16], prev;
int 				vid, pid;
const unsigned char rawVid[2] = {USB_CFG_VENDOR_ID}, rawPid[2] = {USB_CFG_DEVICE_ID};
char                vendor[] = {USB_CFG_VENDOR_NAME, 0}, product[] = {USB_CFG_DEVICE_NAME, 0};
int                 i, nBytes;
int 				error_count = 0, packet_count = 0;
	usb_init();
	
    for(i=1;i<argc;i++){
		if(strcmp(argv[i], "-f") == 0){
            filename = getOptionArg(&i, argc, argv);
        }else{
            fprintf(stderr, "option \"%s\" not recognized.\n", argv[i]);
            usage(argv[0]);
            exit(1);
        }
    }
	
	/* compute VID/PID from usbconfig.h so that there is a central source of information */
	vid = rawVid[1]*256 + rawVid[0];
	pid = rawPid[1]*256 + rawPid[0];
	
restart:    /* we jump back here if an error occurred */
	printf("\nWaiting for device...");	
	/* The following function is in opendevice.c: */
    if(usbOpenDevice(&handle, vid, vendor, pid, product, NULL, NULL, NULL) != 0){
        fprintf(stderr, "Could not find USB device \"%s\" with vid=0x%x pid=0x%x\n", product, vid, pid);
        exit(1);
    }
	printf("Device detected\n");
    if(usb_set_configuration(handle, 1) < 0){
        printf("error setting USB configuration: %s\n", usb_strerror());
    }
    if(usb_claim_interface(handle, 0) < 0){
        printf("error setting USB interface: %s\n", usb_strerror());
    }
   
    signalReopenFile(1);    /* open file */
    for(;;){
        for(;;){    /* read as long as messages are available */
            nBytes = usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, CMD_READ, 0, 0, (char *)buffer, sizeof(buffer), 5000);
            if(nBytes < 0){
                printf("error in USB control transfer: %s\n", usb_strerror());
                goto usbErrorOccurred;
            }
            if(nBytes < 16){
                printf("data format error, only %d bytes received (16 expected)\n", nBytes);
            }else{
				packet_count++;
                printf("[%d]: ", packet_count);
				for(i = 0; i < nBytes; i++) {
					printf("0x%02x  ", buffer[i]);
				}
				if((packet_count > 1) && (buffer[0] != (prev + 1)) ) {
					error_count++;
					printf("\nERROR: %d", error_count);
				}
				prev = buffer[0];
				printf("\n");
            }
			break;
        }
        /* wait for interrupt, set timeout to more than a week */
        nBytes = usb_interrupt_read(handle, USB_ENDPOINT_IN | 1 , (char *)buffer, sizeof(buffer), 700000 * 1000);
        if(nBytes < 0){
            printf("error in USB interrupt read: %s\n", usb_strerror());
            goto usbErrorOccurred;
        }
    }
usbErrorOccurred:
    usb_close(handle);
    sleep(5);
    goto restart;
    return 0;
}
Esempio n. 27
0
static int bfusb_load_firmware(struct bfusb_data *data,
			       const unsigned char *firmware, int count)
{
	unsigned char *buf;
	int err, pipe, len, size, sent = 0;

	BT_DBG("bfusb %p udev %p", data, data->udev);

	BT_INFO("BlueFRITZ! USB loading firmware");

	pipe = usb_sndctrlpipe(data->udev, 0);

	if (usb_control_msg(data->udev, pipe, USB_REQ_SET_CONFIGURATION,
				0, 1, 0, NULL, 0, USB_CTRL_SET_TIMEOUT) < 0) {
		BT_ERR("Can't change to loading configuration");
		return -EBUSY;
	}

	data->udev->toggle[0] = data->udev->toggle[1] = 0;

	buf = kmalloc(BFUSB_MAX_BLOCK_SIZE + 3, GFP_ATOMIC);
	if (!buf) {
		BT_ERR("Can't allocate memory chunk for firmware");
		return -ENOMEM;
	}

	pipe = usb_sndbulkpipe(data->udev, data->bulk_out_ep);

	while (count) {
		size = min_t(uint, count, BFUSB_MAX_BLOCK_SIZE + 3);

		memcpy(buf, firmware + sent, size);

		err = usb_bulk_msg(data->udev, pipe, buf, size,
					&len, BFUSB_BLOCK_TIMEOUT);

		if (err || (len != size)) {
			BT_ERR("Error in firmware loading");
			goto error;
		}

		sent  += size;
		count -= size;
	}

	err = usb_bulk_msg(data->udev, pipe, NULL, 0,
					&len, BFUSB_BLOCK_TIMEOUT);
	if (err < 0) {
		BT_ERR("Error in null packet request");
		goto error;
	}

	pipe = usb_sndctrlpipe(data->udev, 0);

	err = usb_control_msg(data->udev, pipe, USB_REQ_SET_CONFIGURATION,
				0, 2, 0, NULL, 0, USB_CTRL_SET_TIMEOUT);
	if (err < 0) {
		BT_ERR("Can't change to running configuration");
		goto error;
	}

	data->udev->toggle[0] = data->udev->toggle[1] = 0;

	BT_INFO("BlueFRITZ! USB device ready");

	kfree(buf);
	return 0;

error:
	kfree(buf);

	pipe = usb_sndctrlpipe(data->udev, 0);

	usb_control_msg(data->udev, pipe, USB_REQ_SET_CONFIGURATION,
				0, 0, 0, NULL, 0, USB_CTRL_SET_TIMEOUT);

	return err;
}
Esempio n. 28
0
static inline int ssu100_getdevice(struct usb_device *dev, u8 *data)
{
	return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
			       QT_SET_GET_DEVICE, 0xc0, 0, 0,
			       data, 3, 300);
}
static int isight_firmware_load(struct usb_interface *intf,
				const struct usb_device_id *id)
{
	struct usb_device *dev = interface_to_usbdev(intf);
	int llen, len, req, ret = 0;
	const struct firmware *firmware;
	unsigned char *buf = kmalloc(50, GFP_KERNEL);
	unsigned char data[4];
	const u8 *ptr;

	if (!buf)
		return -ENOMEM;

	if (request_firmware(&firmware, "isight.fw", &dev->dev) != 0) {
		printk(KERN_ERR "Unable to load isight firmware\n");
		ret = -ENODEV;
		goto out;
	}

	ptr = firmware->data;

	buf[0] = 0x01;
	if (usb_control_msg
	    (dev, usb_sndctrlpipe(dev, 0), 0xa0, 0x40, 0xe600, 0, buf, 1,
	     300) != 1) {
		printk(KERN_ERR
		       "Failed to initialise isight firmware loader\n");
		ret = -ENODEV;
		goto out;
	}

	while (ptr+4 <= firmware->data+firmware->size) {
		memcpy(data, ptr, 4);
		len = (data[0] << 8 | data[1]);
		req = (data[2] << 8 | data[3]);
		ptr += 4;

		if (len == 0x8001)
			break;	/* success */
		else if (len == 0)
			continue;

		for (; len > 0; req += 50) {
			llen = min(len, 50);
			len -= llen;
			if (ptr+llen > firmware->data+firmware->size) {
				printk(KERN_ERR
				       "Malformed isight firmware");
				ret = -ENODEV;
				goto out;
			}
			memcpy(buf, ptr, llen);

			ptr += llen;

			if (usb_control_msg
			    (dev, usb_sndctrlpipe(dev, 0), 0xa0, 0x40, req, 0,
			     buf, llen, 300) != llen) {
				printk(KERN_ERR
				       "Failed to load isight firmware\n");
				ret = -ENODEV;
				goto out;
			}

		}
	}

	buf[0] = 0x00;
	if (usb_control_msg
	    (dev, usb_sndctrlpipe(dev, 0), 0xa0, 0x40, 0xe600, 0, buf, 1,
	     300) != 1) {
		printk(KERN_ERR "isight firmware loading completion failed\n");
		ret = -ENODEV;
	}

out:
	kfree(buf);
	release_firmware(firmware);
	return ret;
}
Esempio n. 30
0
int main ( int argc, char *argv[] ) {

   // commencer par analyser les options sur la ligne de commande...
   if ( ! analyseLigneDeCommande ( argc, argv ) )
      return -1;

   /* OK, ouvrir tout ce qui est USB... */
   usbOuvrir();
   if ( usbAjustementSerie(USBASP_MODE_SETBAUD2400,
                           USBASP_MODE_UART8BIT, USBASP_MODE_PARITYN ) ) {
      fprintf (stderr, "OK: le peripherique USB est reconnu et la\n");
      fprintf (stderr, "    communication serie doit se faire a 2400 baud,\n");
      fprintf (stderr, "    8 bits et sans parite.\n" );
      fprintf (stderr, "--------------------------------------------\n");
   }
   else {
      fprintf(stderr, "Erreur: incapable d'ajuster la communication serie\n");
      exit (-1);
   }
   fflush(0);

   // lecture et/ou ecriture sans fin
   int i = 0;
   int j = 0;
   int k = 0;
   int rtn;
   int grandeurTampon = 8;
   unsigned char tampon[grandeurTampon];

   //  //thierry a commente
   //struct timespec tempSpec;
   //tempSpec.tv_sec = 0;
   //tempSpec.tv_nsec = 80000000; // 50 ms

   while ( i < nBytes ) {
     // mettre 0xFF dans tout le tampon
     grandeurTampon = 8;
     memset (tampon, 0xFF, grandeurTampon);

     // lecture - le PC recoit les donnees de la carte
     if ( lecture ) {
        rtn = usb_control_msg (gestionUSB,
                   USB_TYPE_VENDOR | USB_RECIP_DEVICE | (1 << 7),
                   USBASP_FUNC_READSER,
                   0, 0, (char *)tampon,
                   grandeurTampon, 5000);
        if ( rtn < 0 ){
          fprintf (stderr, "Erreur: problem de tansmission USB:" );
          fprintf (stderr, " %s\n", usb_strerror());
          usb_close (gestionUSB);
          exit(-1);
        }

        /* le premier octet donne le nombre d'octets vraiment transferes 
           (au maximum 7) */
        if ( tampon[0] < grandeurTampon ) {
           grandeurTampon = tampon[0] + 1;
        }

        j = 1;
        while ( j < grandeurTampon && i < nBytes ) {
          //switch( modeAffichage )
          //{
              //case HEXMODE:
              //    fprintf(fpFichier, "%#04x ", tampon[j]);
              //    break;

              //case DECMODE:
              //    fprintf(fpFichier, "%#04d ", tampon[j]);
              //    break;

              //case BINMODE:
              //    fprintf(fpFichier, "%s ", charToBin(tampon[j]));
              //    break;

              //case BYTEMODE:
              //default:
              fputc (tampon[j], fpFichier);
          //}
        
          if( nbSauts ) {
              if( ( (i+1) % nbSauts) == 0 ) { fputc ('\n', fpFichier); }
          }

          i++;
          j++;
        }
      }
      // le PC envoie les donnees vers la carte
      if ( ecriture ) {
        // remplir le tampon - fpFichier ne peut etre stdin
        j = 1;
        while ( j < grandeurTampon && i < nBytes ) {
          tampon[j] = getc (fpFichier);
          i++;
          j++;
        }
        tampon[0] = j - 1;

        // on envoie vers l'USB  0 == envoie
        rtn = usb_control_msg (gestionUSB,
                   USB_TYPE_VENDOR | USB_RECIP_DEVICE | (0 << 7),
                   USBASP_FUNC_WRITESER,
                   0, 0, (char *)tampon, j, 5000);

        // echo a l'ecran, pas strictement necessaire mais interessant
        for ( k = 0; k < j; k++ )
        {
          //switch( modeAffichage )
          //{
              //case HEXMODE:
              //    fprintf(stderr, "%#04x ", tampon[k]);
              //    break;

              //case DECMODE:
              //    fprintf(stderr, "%#04d ", tampon[k]);
              //    break;

              //case BINMODE:
              //    fprintf(stderr, "%s ", charToBin(tampon[k]));
              //    break;

              //case BYTEMODE:
              //default:
              fputc (tampon[k], stderr);
           //}

           if( nbSauts ) {
               if( ( (k+1) % nbSauts) == 0 ) { fputc ('\n', stderr); }
           }

        }

        // il faut que la carte ecrive les octets en memoire
        // et via l'interface serie qui est lente.  Donner une chance
        // a la carte de realiser ses operations en lui laissant du temps.
        // ce petit delai devrait etre suffisant pour qu'elle 
        // "n'echappe pas des octets" en cours de route...

        // thierry: nanosleep n'existe pas sur windows, alors
        // le but etant d'attendre 50 ms
        // usleep(50) devrait faire l'affaire
        usleep(50);
        //nanosleep (&tempSpec, NULL);

        if ( rtn < 0 ) {
          fprintf (stderr, "Erreur: problem de tansmission USB:" );
          fprintf (stderr, " %s\n", usb_strerror());
          usb_close (gestionUSB);
          exit(-1);
        }
      } /* while */

      fflush(0);
   }

   // rapport indiquant que la transmission est terminee
   fprintf (stderr, "\n--------------------------------------------\n");
   fprintf (stderr, "serieViaUSB : %d octets ont ete transmis ", nBytes );
   fprintf (stderr, "ou recus\n" );
   fflush(0);

   usb_close (gestionUSB);
   return 0;
}