Example #1
0
/*
 * Class:     ch_ntb_usb_LibusbJava
 * Method:    usb_get_descriptor
 * Signature: (JBBI)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_ch_ntb_usb_LibusbJava_usb_1get_1descriptor
  (JNIEnv *env, jclass obj, jlong dev_handle, jbyte type, jbyte index, jint size)
  {
  	clearLibusbJavaError();
	char *string = (char *) malloc(size * sizeof(char));
 	int retVal = usb_get_descriptor((usb_dev_handle *) dev_handle, (unsigned) type,
 										(unsigned) index, string, size);
 	if (retVal > 0)
 		return (*env)->NewStringUTF(env, string);
 	return 0;
  }
Example #2
0
int musb_get_device(MUSB_INTERFACE *usb_interface)
{
#ifdef HAVE_LIBUSB
   struct usb_device_descriptor d;
   usb_get_descriptor(usb_interface->dev, USB_DT_DEVICE, 0, &d, sizeof(d));
   return d.bcdDevice;
#elif HAVE_LIBUSB10
   struct libusb_device_descriptor d;
   libusb_get_descriptor(usb_interface->dev, LIBUSB_DT_DEVICE, 0, (unsigned char *)&d, sizeof(d));
   return d.bcdDevice;
#else
   return 0;
#endif
}
Example #3
0
//-----------------------------------------------------------------
// get_descriptor:
//-----------------------------------------------------------------
static void get_descriptor(struct device_request *request)
{
	unsigned char  bDescriptorType = HI_BYTE(request->wValue);
	unsigned char  bDescriptorIndex = LO_BYTE( request->wValue );
	unsigned short wLength = request->wLength;
	unsigned char  bCount = 0;
    unsigned char *desc_ptr;

    desc_ptr = usb_get_descriptor(bDescriptorType, bDescriptorIndex, wLength, &bCount);

    if (desc_ptr)
        usb_control_send(desc_ptr, bCount);
    else
        usbhw_control_endpoint_stall();
}
Example #4
0
/*
 * usb_get_device_descriptor - (re)reads the device descriptor (usbcore)
 * @dev: the device whose device descriptor is being updated
 * @size: how much of the descriptor to read
 * Context: !in_interrupt ()
 *
 * Updates the copy of the device descriptor stored in the device structure,
 * which dedicates space for this purpose.
 *
 * Not exported, only for use by the core.  If drivers really want to read
 * the device descriptor directly, they can call usb_get_descriptor() with
 * type = USB_DT_DEVICE and index = 0.
 *
 * This call is synchronous, and may not be used in an interrupt context.
 *
 * Returns the number of bytes received on success, or else the status code
 * returned by the underlying usb_control_msg() call.
 */
int usb_get_device_descriptor(struct usb_device *dev, unsigned int size)
{
	struct usb_device_descriptor *desc;
	int ret;

	if (size > sizeof(*desc))
		return -EINVAL;
	desc = kmalloc(sizeof(*desc), GFP_NOIO);
	if (!desc)
		return -ENOMEM;

	ret = usb_get_descriptor(dev, USB_DT_DEVICE, 0, desc, size);
	if (ret >= 0) 
		memcpy(&dev->descriptor, desc, size);
	kfree(desc);
	return ret;
}
Example #5
0
static int get_desc(struct drive_info *drive) {
	struct usb_device_descriptor descriptor;
	usb_dev_handle *udev;

	udev=usb_open(drive->usbdev);
	if(!udev)
		return 1;
	if(usb_get_descriptor(udev,USB_DT_DEVICE,0,&descriptor,sizeof(descriptor))!=sizeof(descriptor)) {
		usb_close(udev);
		return 1;
	}
	if(usb_get_string_simple(udev,descriptor.iProduct,drive->desc,256)<=0) {
		usb_close(udev);
		return 1;
	}
	usb_close(udev);
	return 0;
}
Example #6
0
static int l_usb_get_descriptor(lua_State *L) {
	struct usb_dev_handle * dev_handle = lua_touserdata(L, 1);  
	int type = lua_tonumber(L, 2);  
	int index = lua_tonumber (L, 3);
	int size = lua_tonumber (L, 4);
	
	if (size==0) {size=255;} //default value
	char buf[size];
	int ret = usb_get_descriptor(dev_handle,
			(unsigned char)type, (unsigned char)index, buf, size);
	
	if( ret < 0 ) {
		lua_pushnil (L);
		lua_pushnumber (L, ret);
		return 2; /* number of results */   
	} else{
		lua_pushlstring (L, buf, ret);
		return 1; /* number of results */   
	}
}
Example #7
0
/* USB::DevHandle#usb_get_descriptor(type, index, buf) */
static VALUE
rusb_get_descriptor(
  VALUE v,
  VALUE vtype,
  VALUE vindex,
  VALUE vbuf)
{
  usb_dev_handle *p = get_usb_devhandle(v);
  int type = NUM2INT(vtype);
  int index = NUM2INT(vindex);
  char *buf;
  int buflen;
  int ret;
  StringValue(vbuf);
  rb_str_modify(vbuf);
  buf = RSTRING_PTR(vbuf);
  buflen = RSTRING_LEN(vbuf);
  ret = usb_get_descriptor(p, type, index, buf, buflen);
  check_usb_error("usb_get_descriptor", ret);
  return INT2NUM(ret);
}
Example #8
0
/**
 * usb_get_device_descriptor - (re)reads the device descriptor
 * @dev: the device whose device descriptor is being updated
 * @size: how much of the descriptor to read
 * Context: !in_interrupt ()
 *
 * Updates the copy of the device descriptor stored in the device structure,
 * which dedicates space for this purpose.  Note that several fields are
 * converted to the host CPU's byte order:  the USB version (bcdUSB), and
 * vendors product and version fields (idVendor, idProduct, and bcdDevice).
 * That lets device drivers compare against non-byteswapped constants.
 *
 * Not exported, only for use by the core.  If drivers really want to read
 * the device descriptor directly, they can call usb_get_descriptor() with
 * type = USB_DT_DEVICE and index = 0.
 *
 * This call is synchronous, and may not be used in an interrupt context.
 *
 * Returns the number of bytes received on success, or else the status code
 * returned by the underlying usb_control_msg() call.
 */
int usb_get_device_descriptor(struct usb_device *dev, unsigned int size)
{
	struct usb_device_descriptor *desc;
	int ret;

	if (size > sizeof(*desc))
		return -EINVAL;
	desc = kmalloc(sizeof(*desc), GFP_NOIO);
	if (!desc)
		return -ENOMEM;

	ret = usb_get_descriptor(dev, USB_DT_DEVICE, 0, desc, size);
	if (ret >= 0) {
		le16_to_cpus(&desc->bcdUSB);
		le16_to_cpus(&desc->idVendor);
		le16_to_cpus(&desc->idProduct);
		le16_to_cpus(&desc->bcdDevice);
		memcpy(&dev->descriptor, desc, size);
	}
	msleep(1);
	kfree(desc);
	return ret;
}
//! usb_process_request.
//!
//! @brief This function reads the SETUP request sent to the default control endpoint
//! and calls the appropriate function. When exiting of the usb_read_request
//! function, the device is ready to manage the next request.
//!
//! @note list of supported requests:
//! GET_DESCRIPTOR
//! GET_CONFIGURATION
//! SET_ADDRESS
//! SET_CONFIGURATION
//! CLEAR_FEATURE
//! SET_FEATURE
//! GET_STATUS
//!
void usb_process_request(void)
{
   U8  bmRequest;

   bmRequestType = Usb_read_byte();
   bmRequest     = Usb_read_byte();

   switch (bmRequest)
   {
    case GET_DESCRIPTOR:
         if (0x80 == bmRequestType) { usb_get_descriptor(); }
         else goto user_read;
         break;

    case GET_CONFIGURATION:
         if (0x80 == bmRequestType) { usb_get_configuration(); }
         else goto user_read;
         break;

    case SET_ADDRESS:
         if (0x00 == bmRequestType) { usb_set_address(); }
         else goto user_read;
         break;

    case SET_CONFIGURATION:
         if (0x00 == bmRequestType) { usb_set_configuration(); }
         else goto user_read;
         break;

    case CLEAR_FEATURE:
         if (0x02 >= bmRequestType) { usb_clear_feature(); }
         else goto user_read;
         break;

    case SET_FEATURE:
         if (0x02 >= bmRequestType) { usb_set_feature(); }
         else goto user_read;
         break;

    case GET_STATUS:
         if ((0x7F < bmRequestType) & (0x82 >= bmRequestType))
                                    { usb_get_status(); }
         else goto user_read;
         break;

    case GET_INTERFACE:
          if (bmRequestType == 0x81) { usb_get_interface(); }
		  else goto user_read;
          break;


    case SET_INTERFACE:
      if (bmRequestType == 0x01) {usb_set_interface();}
      break;

    case SET_DESCRIPTOR:
    case SYNCH_FRAME:
    default: //!< un-supported request => call to user read request
	user_read:
         usb_user_read_request(bmRequestType, bmRequest);
         break;
  }
	
	Usb_select_endpoint(EP_CONTROL);

	// If the receive setup flag hasn't been cleared
	// by this point then we can assume that we didn't
	// support this request and should stall.
	if(Is_usb_receive_setup())
		Usb_enable_stall_handshake();
	
	// Clear some flags.
	Usb_ack_receive_setup();
	Usb_ack_receive_out();
	Usb_ack_in_ready();
}
void usb_fetch_and_parse_descriptors(usb_dev_handle *udev)
{
  struct usb_device *dev = udev->device;
  int i;

  if (dev->descriptor.bNumConfigurations > USB_MAXCONFIG) {
    if (usb_debug >= 1)
      fprintf(stderr, "Too many configurations (%d > %d)\n", dev->descriptor.bNumConfigurations, USB_MAXCONFIG);
    return;
  }

  if (dev->descriptor.bNumConfigurations < 1) {
    if (usb_debug >= 1)
      fprintf(stderr, "Not enough configurations (%d < %d)\n", dev->descriptor.bNumConfigurations, 1);
    return;
  }

  dev->config = (struct usb_config_descriptor *)malloc(dev->descriptor.bNumConfigurations * sizeof(struct usb_config_descriptor));
  if (!dev->config) {
    if (usb_debug >= 1)
      fprintf(stderr, "Unable to allocate memory for config descriptor\n");
    return;
  }

  memset(dev->config, 0, dev->descriptor.bNumConfigurations *
	sizeof(struct usb_config_descriptor));

  for (i = 0; i < dev->descriptor.bNumConfigurations; i++) {
    unsigned char buffer[8], *bigbuffer;
    struct usb_config_descriptor config;
    int res;

    /* Get the first 8 bytes so we can figure out what the total length is */
    res = usb_get_descriptor(udev, USB_DT_CONFIG, (unsigned char)i, buffer, 8);
    if (res < 8) {
      if (usb_debug >= 1) {
        if (res < 0)
          fprintf(stderr, "Unable to get descriptor (%d)\n", res);
        else
          fprintf(stderr, "Config descriptor too short (expected %d, got %d)\n", 8, res);
      }

      goto err;
    }

    usb_parse_descriptor(buffer, "bbw", &config);

    bigbuffer = malloc(config.wTotalLength);
    if (!bigbuffer) {
      if (usb_debug >= 1)
        fprintf(stderr, "Unable to allocate memory for descriptors\n");
      goto err;
    }

    res = usb_get_descriptor(udev, USB_DT_CONFIG, (unsigned char)i, bigbuffer,
                             config.wTotalLength);
    if (res < config.wTotalLength) {
      if (usb_debug >= 1) {
        if (res < 0)
          fprintf(stderr, "Unable to get descriptor (%d)\n", res);
        else
          fprintf(stderr, "Config descriptor too short (expected %d, got %d)\n", config.wTotalLength, res);
      }

      free(bigbuffer);
      goto err;
    }

    res = usb_parse_configuration(&dev->config[i], bigbuffer);
    if (usb_debug >= 2) {
      if (res > 0)
        fprintf(stderr, "Descriptor data still left\n");
      else if (res < 0)
        fprintf(stderr, "Unable to parse descriptors\n");
    }

    free(bigbuffer);
  }

  return;

err:
  free(dev->config);

  dev->config = NULL;
}
Example #11
0
/* This function reads the Microsoft OS Descriptor and looks inside to
 * find if it is a MTP device. This is the similar to the way that
 * Windows Media Player 10 uses.
 * It is documented to some degree on various internet pages.
 */
static int
gp_libusb1_match_mtp_device(struct libusb_device *dev,int *configno, int *interfaceno, int *altsettingno)
{
	/* Marcus: Avoid this probing altogether, its too unstable on some devices */
	return 0;

#if 0
	char buf[1000], cmd;
	int ret,i,i1,i2, xifaces,xnocamifaces;
	usb_dev_handle *devh;

	/* All of them are "vendor specific" device class */
#if 0
	if ((desc.bDeviceClass!=0xff) && (desc.bDeviceClass!=0))
		return 0;
#endif
	if (dev->config) {
		xifaces = xnocamifaces = 0;
		for (i = 0; i < desc.bNumConfigurations; i++) {
			unsigned int j;

			for (j = 0; j < dev->config[i].bNumInterfaces; j++) {
				int k;
				xifaces++;

				for (k = 0; k < dev->config[i].interface[j].num_altsetting; k++) {
					struct usb_interface_descriptor *intf = &dev->config[i].interface[j].altsetting[k]; 
					if (	(intf->bInterfaceClass == LIBUSB_CLASS_HID)	||
						(intf->bInterfaceClass == LIBUSB_CLASS_PRINTER)	||
						(intf->bInterfaceClass == LIBUSB_CLASS_AUDIO)	||
						(intf->bInterfaceClass == LIBUSB_CLASS_HUB)	||
						(intf->bInterfaceClass == LIBUSB_CLASS_COMM)	||
						(intf->bInterfaceClass == 0xe0)	/* wireless/bluetooth*/
					)
						xnocamifaces++;
				}
			}
		}
	}
	if (xifaces == xnocamifaces) /* only non-camera ifaces */
		return 0;

	devh = usb_open (dev);
	if (!devh)
		return 0;

	/*
	 * Loop over the device configurations and interfaces. Nokia MTP-capable 
	 * handsets (possibly others) typically have the string "MTP" in their 
	 * MTP interface descriptions, that's how they can be detected, before
	 * we try the more esoteric "OS descriptors" (below).
	 */
	if (dev->config) {
		for (i = 0; i < desc.bNumConfigurations; i++) {
			unsigned int j;

			for (j = 0; j < dev->config[i].bNumInterfaces; j++) {
				int k;
				for (k = 0; k < dev->config[i].interface[j].num_altsetting; k++) {
					buf[0] = '\0';
					ret = usb_get_string_simple(devh, 
						dev->config[i].interface[j].altsetting[k].iInterface, 
						(char *) buf, 
						1024);
					if (ret < 3)
						continue;
					if (strcmp((char *) buf, "MTP") == 0) {
						GP_LOG_D ("Configuration %d, interface %d, altsetting %d:\n", i, j, k);
						GP_LOG_D ("   Interface description contains the string \"MTP\"\n");
						GP_LOG_D ("   Device recognized as MTP, no further probing.\n");
						goto found;
					}
				}
			}
		}
	}
	/* get string descriptor at 0xEE */
	ret = usb_get_descriptor (devh, 0x03, 0xee, buf, sizeof(buf));
	if (ret > 0) GP_LOG_DATA (buf, ret, "get_MS_OSD");
	if (ret < 10) goto errout;
	if (!((buf[2] == 'M') && (buf[4]=='S') && (buf[6]=='F') && (buf[8]=='T')))
		goto errout;
	cmd = buf[16];
	ret = usb_control_msg (devh, USB_ENDPOINT_IN|USB_RECIP_DEVICE|LIBUSB_REQUEST_TYPE_VENDOR, cmd, 0, 4, buf, sizeof(buf), 1000);
	if (ret == -1) {
		GP_LOG_E ("control message says %d\n", ret);
		goto errout;
	}
	if (buf[0] != 0x28) {
		GP_LOG_E ("ret is %d, buf[0] is %x\n", ret, buf[0]);
		goto errout;
	}
	if (ret > 0) GP_LOG_DATA (buf, ret, "get_MS_ExtDesc");
	if ((buf[0x12] != 'M') || (buf[0x13] != 'T') || (buf[0x14] != 'P')) {
		GP_LOG_E ("buf at 0x12 is %02x%02x%02x\n", buf[0x12], buf[0x13], buf[0x14]);
		goto errout;
	}
	ret = usb_control_msg (devh, USB_ENDPOINT_IN|USB_RECIP_DEVICE|LIBUSB_REQUEST_TYPE_VENDOR, cmd, 0, 5, buf, sizeof(buf), 1000);
	if (ret == -1) goto errout;
	if (buf[0] != 0x28) {
		GP_LOG_E ("ret is %d, buf[0] is %x\n", ret, buf[0]);
		goto errout;
	}
	if (ret > 0) GP_LOG_DATA (buf, ret, "get_MS_ExtProp");
	if ((buf[0x12] != 'M') || (buf[0x13] != 'T') || (buf[0x14] != 'P')) {
		GP_LOG_E ("buf at 0x12 is %02x%02x%02x\n", buf[0x12], buf[0x13], buf[0x14]);
		goto errout;
	}

found:
	usb_close (devh);

	/* Now chose a nice interface for us to use ... Just take the first. */

	if (desc.bNumConfigurations > 1)
		GP_LOG_E ("The device has %d configurations!\n", desc.bNumConfigurations);
	for (i = 0; i < desc.bNumConfigurations; i++) {
		struct usb_config_descriptor *config =
			&dev->config[i];

		if (config->bNumInterfaces > 1)
			GP_LOG_E ("The configuration has %d interfaces!\n", config->bNumInterfaces);
		for (i1 = 0; i1 < config->bNumInterfaces; i1++) {
			struct usb_interface *interface =
				&config->interface[i1];

			if (interface->num_altsetting > 1)
				GP_LOG_E ("The interface has %d altsettings!\n", interface->num_altsetting);
			for (i2 = 0; i2 < interface->num_altsetting; i2++) {
				*configno = i;
				*interfaceno = i1;
				*altsettingno = i2;
				return 1;
			}
		}
	}
	return 1;
errout:
	usb_close (devh);
	return 0;
#endif
}
Example #12
0
/*
 * Get the USB config descriptors, cache and parse'em
 *
 * hub-only!! ... and only in reset path, or usb_new_device()
 * (used by real hubs and virtual root hubs)
 *
 * NOTE: if this is a WUSB device and is not authorized, we skip the
 *       whole thing. A non-authorized USB device has no
 *       configurations.
 */
int usb_get_configuration(struct usb_device *dev)
{
	struct device *ddev = &dev->dev;
	int ncfg = dev->descriptor.bNumConfigurations;
	int result = 0;
	unsigned int cfgno, length;
	unsigned char *buffer;
	unsigned char *bigbuffer;
 	struct usb_config_descriptor *desc;

	cfgno = 0;
	if (dev->authorized == 0)	/* Not really an error */
		goto out_not_authorized;
	result = -ENOMEM;
	if (ncfg > USB_MAXCONFIG) {
		dev_warn(ddev, "too many configurations: %d, "
		    "using maximum allowed: %d\n", ncfg, USB_MAXCONFIG);
		dev->descriptor.bNumConfigurations = ncfg = USB_MAXCONFIG;
	}

	if (ncfg < 1) {
		dev_err(ddev, "no configurations\n");
		return -EINVAL;
	}

	length = ncfg * sizeof(struct usb_host_config);
	dev->config = kzalloc(length, GFP_KERNEL);
	if (!dev->config)
		goto err2;

	length = ncfg * sizeof(char *);
	dev->rawdescriptors = kzalloc(length, GFP_KERNEL);
	if (!dev->rawdescriptors)
		goto err2;

	buffer = kmalloc(USB_DT_CONFIG_SIZE, GFP_KERNEL);
	if (!buffer)
		goto err2;
	desc = (struct usb_config_descriptor *)buffer;

	result = 0;
	for (; cfgno < ncfg; cfgno++) {
		/* We grab just the first descriptor so we know how long
		 * the whole configuration is */
		result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno,
		    buffer, USB_DT_CONFIG_SIZE);
		if (result < 0) {
			dev_err(ddev, "unable to read config index %d "
			    "descriptor/%s: %d\n", cfgno, "start", result);
			dev_err(ddev, "chopping to %d config(s)\n", cfgno);
			dev->descriptor.bNumConfigurations = cfgno;
			break;
		} else if (result < 4) {
			dev_err(ddev, "config index %d descriptor too short "
			    "(expected %i, got %i)\n", cfgno,
			    USB_DT_CONFIG_SIZE, result);
			result = -EINVAL;
			goto err;
		}
		length = max((int) le16_to_cpu(desc->wTotalLength),
		    USB_DT_CONFIG_SIZE);

		/* Now that we know the length, get the whole thing */
		bigbuffer = kmalloc(length, GFP_KERNEL);
		if (!bigbuffer) {
			result = -ENOMEM;
			goto err;
		}
		result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno,
		    bigbuffer, length);
		if (result < 0) {
			dev_err(ddev, "unable to read config index %d "
			    "descriptor/%s\n", cfgno, "all");
			kfree(bigbuffer);
			goto err;
		}
		if (result < length) {
			dev_warn(ddev, "config index %d descriptor too short "
			    "(expected %i, got %i)\n", cfgno, length, result);
			length = result;
		}

#if defined(__VMKLNX__)
		dev->rawdescriptors[cfgno] = (char *)bigbuffer;
#else
		dev->rawdescriptors[cfgno] = bigbuffer;
#endif

		result = usb_parse_configuration(&dev->dev, cfgno,
		    &dev->config[cfgno], bigbuffer, length);
		if (result < 0) {
			++cfgno;
			goto err;
		}
	}
	result = 0;

err:
	kfree(buffer);
out_not_authorized:
	dev->descriptor.bNumConfigurations = cfgno;
err2:
	if (result == -ENOMEM)
		dev_err(ddev, "out of memory\n");
	return result;
}
Example #13
0
static int probe_device_descriptor(struct usb_device *dev, FILE *dumpfile)
{
  usb_dev_handle *devh;
  unsigned char buf[1024], cmd;
  int i;
  int ret;
  
  
  if (dev->descriptor.bDeviceClass == USB_CLASS_HUB) {
    return 0;
  }
  
  
  devh = usb_open(dev);
  if (devh == NULL) {
    
    return 0;
  }

  if (dev->config) {
    for (i = 0; i < dev->descriptor.bNumConfigurations; i++) {
      uint8_t j;

      for (j = 0; j < dev->config[i].bNumInterfaces; j++) {
        int k;
        for (k = 0; k < dev->config[i].interface[j].num_altsetting; k++) {
	  
	  struct usb_interface_descriptor *intf =
	    &dev->config[i].interface[j].altsetting[k];


          buf[0] = '\0';
          ret = usb_get_string_simple(devh,
				      dev->config[i].interface[j].altsetting[k].iInterface,
				      (char *) buf,
				      1024);
	  if (ret < 3)
	    continue;
          if (strcmp((char *) buf, "MTP") == 0) {
	    if (dumpfile != NULL) {
              fprintf(dumpfile, "Configuration %d, interface %d, altsetting %d:\n", i, j, k);
	      fprintf(dumpfile, "   Interface description contains the string \"MTP\"\n");
	      fprintf(dumpfile, "   Device recognized as MTP, no further probing.\n");
	    }
            usb_close(devh);
            return 1;
          }
  #ifdef LIBUSB_HAS_GET_DRIVER_NP
	  {
	    char devname[0x10];

	    devname[0] = '\0';
	    ret = usb_get_driver_np(devh,
				    dev->config[i].interface[j].altsetting[k].iInterface,
				    devname,
				    sizeof(devname));
	    if (devname[0] != '\0' && strcmp(devname, "usb-storage")) {
	      printf("avoid probing device using kernel interface \"%s\"\n", devname);
	      return 0;
	    }
	  }
  #endif
        }
      }
    }
  } else {
    if (dev->descriptor.bNumConfigurations)
      printf("dev->config is NULL in probe_device_descriptor yet dev->descriptor.bNumConfigurations > 0\n");
  }
  
  
  ret = usb_get_descriptor(devh, 0x03, 0xee, buf, sizeof(buf));

  
  if (dumpfile != NULL && ret > 0) {
    fprintf(dumpfile, "Microsoft device descriptor 0xee:\n");
    data_dump_ascii(dumpfile, buf, ret, 16);
  }
  
  
  if (ret < 10) {
    usb_close(devh);
    return 0;
  }
      
  
  if (!((buf[2] == 'M') && (buf[4] == 'S') &&
	(buf[6] == 'F') && (buf[8] == 'T'))) {
    usb_close(devh);
    return 0;
  }
      
  
  cmd = buf[16];
  ret = usb_control_msg (devh,
			 USB_ENDPOINT_IN|USB_RECIP_DEVICE|USB_TYPE_VENDOR,
			 cmd,
			 0,
			 4,
			 (char *) buf,
			 sizeof(buf),
                         USB_TIMEOUT_DEFAULT);

  
  if (dumpfile != NULL && ret > 0) {
    fprintf(dumpfile, "Microsoft device response to control message 1, CMD 0x%02x:\n", cmd);
    data_dump_ascii(dumpfile, buf, ret, 16);
  }
  
  
  if (ret <= 0x15) {
    
    
    usb_close(devh);
    return 0;
  }
  
  if ((buf[0x12] != 'M') || (buf[0x13] != 'T') || (buf[0x14] != 'P')) {
    usb_close(devh);
    return 0;
  }
      
  

  
  ret = usb_control_msg (devh,
			 USB_ENDPOINT_IN|USB_RECIP_DEVICE|USB_TYPE_VENDOR,
			 cmd,
			 0,
			 5,
			 (char *) buf,
			 sizeof(buf),
                         USB_TIMEOUT_DEFAULT);

  
  if (dumpfile != NULL && ret > 0) {
    fprintf(dumpfile, "Microsoft device response to control message 2, CMD 0x%02x:\n", cmd);
    data_dump_ascii(dumpfile, buf, ret, 16);
  }
  
  
  if (ret == -1) {
    fprintf(stderr, "Potential MTP Device with VendorID:%04x and "
	    "ProductID:%04x encountered an error responding to "
	    "control message 2.\n"
	    "Problems may arrise but continuing\n",
	    dev->descriptor.idVendor, dev->descriptor.idProduct);
  } else if (ret <= 0x15) {
    fprintf(stderr, "Potential MTP Device with VendorID:%04x and "
	    "ProductID:%04x responded to control message 2 with a "
	    "response that was too short. Problems may arrise but "
	    "continuing\n",
	    dev->descriptor.idVendor, dev->descriptor.idProduct);
  } else if ((buf[0x12] != 'M') || (buf[0x13] != 'T') || (buf[0x14] != 'P')) {
    fprintf(stderr, "Potential MTP Device with VendorID:%04x and "
	    "ProductID:%04x encountered an error responding to "
	    "control message 2\n"
	    "Problems may arrise but continuing\n",
	    dev->descriptor.idVendor, dev->descriptor.idProduct);
  }
  
  
  usb_close(devh);
  return 1;
}
Example #14
0
File: config.c Project: 7799/linux
/* Get BOS descriptor set */
int usb_get_bos_descriptor(struct usb_device *dev)
{
	struct device *ddev = &dev->dev;
	struct usb_bos_descriptor *bos;
	struct usb_dev_cap_header *cap;
	unsigned char *buffer;
	int length, total_len, num, i;
	int ret;

	bos = kzalloc(sizeof(struct usb_bos_descriptor), GFP_KERNEL);
	if (!bos)
		return -ENOMEM;

	/* Get BOS descriptor */
	ret = usb_get_descriptor(dev, USB_DT_BOS, 0, bos, USB_DT_BOS_SIZE);
	if (ret < USB_DT_BOS_SIZE) {
		dev_err(ddev, "unable to get BOS descriptor\n");
		if (ret >= 0)
			ret = -ENOMSG;
		kfree(bos);
		return ret;
	}

	length = bos->bLength;
	total_len = le16_to_cpu(bos->wTotalLength);
	num = bos->bNumDeviceCaps;
	kfree(bos);
	if (total_len < length)
		return -EINVAL;

	dev->bos = kzalloc(sizeof(struct usb_host_bos), GFP_KERNEL);
	if (!dev->bos)
		return -ENOMEM;

	/* Now let's get the whole BOS descriptor set */
	buffer = kzalloc(total_len, GFP_KERNEL);
	if (!buffer) {
		ret = -ENOMEM;
		goto err;
	}
	dev->bos->desc = (struct usb_bos_descriptor *)buffer;

	ret = usb_get_descriptor(dev, USB_DT_BOS, 0, buffer, total_len);
	if (ret < total_len) {
		dev_err(ddev, "unable to get BOS descriptor set\n");
		if (ret >= 0)
			ret = -ENOMSG;
		goto err;
	}
	total_len -= length;

	for (i = 0; i < num; i++) {
		buffer += length;
		cap = (struct usb_dev_cap_header *)buffer;
		length = cap->bLength;

		if (total_len < length)
			break;
		total_len -= length;

		if (cap->bDescriptorType != USB_DT_DEVICE_CAPABILITY) {
			dev_warn(ddev, "descriptor type invalid, skip\n");
			continue;
		}

		switch (cap->bDevCapabilityType) {
		case USB_CAP_TYPE_WIRELESS_USB:
			/* Wireless USB cap descriptor is handled by wusb */
			break;
		case USB_CAP_TYPE_EXT:
			dev->bos->ext_cap =
				(struct usb_ext_cap_descriptor *)buffer;
			break;
		case USB_SS_CAP_TYPE:
			dev->bos->ss_cap =
				(struct usb_ss_cap_descriptor *)buffer;
			break;
		case CONTAINER_ID_TYPE:
			dev->bos->ss_id =
				(struct usb_ss_container_id_descriptor *)buffer;
			break;
		default:
			break;
		}
	}

	return 0;

err:
	usb_release_bos_descriptor(dev);
	return ret;
}
Example #15
0
/* XXX: exclude high speed devices or implement EHCI */
USBDevice *usb_host_device_open(const char *devname)
{
    USBHostDevice *dev;
    struct usb_dev_handle *udev = NULL;
    struct usb_device *device = NULL;
    struct usb_config_descriptor config_desc;
    int config_descr_len, nb_interfaces;
    int bus_num, addr, interface, ret;
    char product_name[32] ;
    
    if ((ret = usb_host_find_device(&bus_num, &addr, devname, &device)) < 0) 
        return NULL;

    if (!device)
        return NULL;
    
    udev = usb_open(device);

    if (!udev) {
#ifdef DEBUG
        printf("couldn't open usb device at %d.%d\n", bus_num, addr);
#endif
        return NULL;
    }
    
    /* read the 1st config descriptor */
    config_descr_len = usb_get_descriptor(udev, 2, 0, &config_desc, sizeof(config_desc));
    if (config_descr_len <= 0) {
        printf("read config_desc: %s", usb_strerror());
        goto fail;
    }
    
    if (config_descr_len > sizeof(config_desc)) {
        printf("config_desc size mismatch\n");
        goto fail;
    }
        
    nb_interfaces = config_desc.bNumInterfaces;
    usb_set_configuration(udev, config_desc.bConfigurationValue);
    
    for (interface = 0; interface < nb_interfaces; interface++) {
        /* might as well */
#ifdef LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP
        usb_detach_kernel_driver_np(udev, interface);
#endif
    
        ret = usb_claim_interface(udev, interface);
    
        if (ret < 0) {
            printf("usb_claim_interface: %s", usb_strerror());
        fail:
            if (udev)
                usb_close(udev);
            return NULL;
        }
    }

#ifdef DEBUG
    printf("host USB device %d.%d grabbed\n", bus_num, addr);
#endif

    dev = qemu_mallocz(sizeof(USBHostDevice));
    if (!dev)
        goto fail;
    
    /* not accurate - might be better off reporting only low/full */
    switch (device->descriptor.bcdUSB) {
        case 0x0110:
            dev->dev.speed = USB_SPEED_FULL;
            break;
        case 0x0200:
            dev->dev.speed = USB_SPEED_HIGH;
            break;
        case 0x0100:
            dev->dev.speed = USB_SPEED_LOW;
            break;
        default:
            dev->dev.speed = USB_SPEED_FULL;
    }
    
    dev->udev = udev;
    dev->num_interfaces = nb_interfaces;
    dev->dev.handle_packet = usb_generic_handle_packet;

    dev->dev.handle_reset = usb_host_handle_reset;
    dev->dev.handle_control = usb_host_handle_control;
    dev->dev.handle_data = usb_host_handle_data;
    dev->dev.handle_destroy = usb_host_handle_destroy;
    
    /* get product string if available */
    usb_get_string_simple(udev, device->descriptor.iProduct,
                                   product_name, sizeof(product_name));
    
    if (product_name[0] == '\0')
        snprintf(dev->dev.devname, sizeof(dev->dev.devname),
                   "host:%s", devname);
    else
        pstrcpy(dev->dev.devname, sizeof(dev->dev.devname),
                   product_name);
    
    return (USBDevice *)dev;
}
Example #16
0
File: main.c Project: 1butler1/xpwn
int download(AbstractFile* file, unsigned int transfer_size, int final_reset)
{
	struct dfu_if _rt_dif, _dif, *dif = &_dif;
	int num_devs;
	int num_ifs;
	enum mode mode = MODE_NONE;
	struct dfu_status status;
	struct usb_dfu_func_descriptor func_dfu;
	char *alt_name = NULL; /* query alt name if non-NULL */
	int ret;
	
	printf("dfu-util - (C) 2007 by OpenMoko Inc. Hacked by the iPhone Dev Team\n"
	       "This program is Free Software and has ABSOLUTELY NO WARRANTY\n\n");

	memset(dif, 0, sizeof(*dif));

	dif->flags = DFU_IFF_VENDOR | DFU_IFF_PRODUCT;
	dif->vendor = 0x05ac;
	dif->product = 0x1222;
	dif->product_mask = 0xfff0;

	usb_init();
	//usb_set_debug(255);
	usb_find_busses();
	usb_find_devices();

	mode = MODE_DOWNLOAD;

	if (mode == MODE_NONE) {
		fprintf(stderr, "You need to specify one of -D or -U\n");
		help();
		exit(2);
	}

	if (!file) {
		fprintf(stderr, "You need to specify a filename to -D -r -U\n");
		help();
		exit(2);
	}

	dfu_init(5000);

	num_devs = count_dfu_devices(dif);
	if (num_devs == 0) {
		fprintf(stderr, "No DFU capable USB device found\n");
		exit(1);
	} else if (num_devs > 1) {
		/* We cannot safely support more than one DFU capable device
		 * with same vendor/product ID, since during DFU we need to do
		 * a USB bus reset, after which the target device will get a
		 * new address */
		fprintf(stderr, "More than one DFU capable USB device found, "
		       "you might try `--list' and then disconnect all but one "
		       "device\n");
		exit(3);
	}
	if (!get_first_dfu_device(dif))
		exit(3);

	/* We have exactly one device. It's usb_device is now in dif->dev */

	printf("Opening USB Device 0x%04x:0x%04x...\n", dif->vendor, dif->product);
	dif->dev_handle = usb_open(dif->dev);
	if (!dif->dev_handle) {
		fprintf(stderr, "Cannot open device: %s\n", usb_strerror());
		exit(1);
	}

	/* try to find first DFU interface of device */
	memcpy(&_rt_dif, dif, sizeof(_rt_dif));
	if (!get_first_dfu_if(&_rt_dif))
		exit(1);

	if (alt_name) {
		int n;

		n = find_dfu_if(dif->dev, &alt_by_name, alt_name);
		if (!n) {
			fprintf(stderr, "No such Alternate Setting: \"%s\"\n",
			    alt_name);
			exit(1);
		}
		if (n < 0) {
			fprintf(stderr, "Error %d in name lookup\n", n);
			exit(1);
		}
		dif->altsetting = n-1;
	}

	print_dfu_if(dif, NULL);

	num_ifs = count_dfu_interfaces(dif->dev);
	if (num_ifs < 0) {
		fprintf(stderr, "No DFU Interface after RESET?!?\n");
		exit(1);
	} else if (num_ifs == 1) {
		if (!get_first_dfu_if(dif)) {
			fprintf(stderr, "Can't find the single available DFU IF\n");
			exit(1);
		}
	} else if (num_ifs > 1 && !dif->flags & (DFU_IFF_IFACE|DFU_IFF_ALT)) {
		fprintf(stderr, "We have %u DFU Interfaces/Altsettings, "
			"you have to specify one via --intf / --alt options\n",
			num_ifs);
		exit(1);
	}

	dif->configuration = 1;
	printf("Setting Configuration %u...\n", dif->configuration);
	if (usb_set_configuration(dif->dev_handle, dif->configuration) < 0) {
		fprintf(stderr, "Cannot set configuration: %s\n", usb_strerror());
	}

	printf("Claiming USB DFU Interface...\n");
	if (usb_claim_interface(dif->dev_handle, dif->interface) < 0) {
		fprintf(stderr, "Cannot claim interface: %s\n", usb_strerror());
	}

	printf("Setting Alternate Setting ...\n");
	if (usb_set_altinterface(dif->dev_handle, dif->altsetting) < 0) {
		fprintf(stderr, "Cannot set alternate interface: %s\n",
			usb_strerror());
	}

status_again:
	printf("Determining device status: ");
	if (dfu_get_status(dif->dev_handle, dif->interface, &status ) < 0) {
		fprintf(stderr, "error get_status: %s\n", usb_strerror());
		exit(1);
	}
	printf("state = %s, status = %d\n", dfu_state_to_string(status.bState), status.bStatus);

	switch (status.bState) {
	case DFU_STATE_appIDLE:
	case DFU_STATE_appDETACH:
		fprintf(stderr, "Device still in Runtime Mode!\n");
		exit(1);
		break;
	case DFU_STATE_dfuERROR:
		printf("dfuERROR, clearing status\n");
		if (dfu_clear_status(dif->dev_handle, dif->interface) < 0) {
			fprintf(stderr, "error clear_status: %s\n", usb_strerror());
			exit(1);
		}
		goto status_again;
		break;
	case DFU_STATE_dfuDNLOAD_IDLE:
	case DFU_STATE_dfuUPLOAD_IDLE:
		printf("aborting previous incomplete transfer\n");
		if (dfu_abort(dif->dev_handle, dif->interface) < 0) {
			fprintf(stderr, "can't send DFU_ABORT: %s\n", usb_strerror());
			exit(1);
		}
		goto status_again;
		break;
	case DFU_STATE_dfuIDLE:
		printf("dfuIDLE, continuing\n");
		break;
	}

	if (!transfer_size) {
		/* Obtain DFU functional descriptor */
		ret = usb_get_descriptor(dif->dev_handle, 0x21, dif->interface,
					 &func_dfu, sizeof(func_dfu));
		if (ret < 0) {
			fprintf(stderr, "Error obtaining DFU functional "
				"descriptor: %s\n", usb_strerror());
			transfer_size = 0x800;
		} else {
			func_dfu.wTransferSize = LE2CPU16(func_dfu.wTransferSize);
			transfer_size = func_dfu.wTransferSize;
		}
	}

	printf("Transfer Size = 0x%04x\n", transfer_size);

	if (DFU_STATUS_OK != status.bStatus ) {
		printf("WARNING: DFU Status: '%s'\n",
			dfu_status_to_string(status.bStatus));
		/* Clear our status & try again. */
		dfu_clear_status(dif->dev_handle, dif->interface);
		dfu_get_status(dif->dev_handle, dif->interface, &status);

		if (DFU_STATUS_OK != status.bStatus) {
			fprintf(stderr, "Error: %d\n", status.bStatus);
			exit(1);
		}
        }

	switch (mode) {
	case MODE_DOWNLOAD:
		if (sam7dfu_do_dnload(dif->dev_handle, dif->interface,
				  transfer_size, file) < 0) {
			usb_release_interface(dif->dev_handle, dif->interface);
			return 1;
		}
		break;
	default:
		fprintf(stderr, "Unsupported mode: %u\n", mode);
		exit(1);
	}

	if (final_reset) {
		if (dfu_detach(dif->dev_handle, dif->interface, 1000) < 0) {
			fprintf(stderr, "can't detach: %s\n", usb_strerror());
		}
		printf("Resetting USB to switch back to runtime mode\n");
		ret = usb_reset(dif->dev_handle);
		if (ret < 0 && ret != -ENODEV) {
			fprintf(stderr, "error resetting after download: %s\n", 
			usb_strerror());
		}
	}

	if(usb_release_interface(dif->dev_handle, dif->interface) < 0) {
		fprintf(stderr, "error: releasing %s\n", usb_strerror());
	}

	if(usb_close(dif->dev_handle) < 0) {
		fprintf(stderr, "error: closing %s\n", usb_strerror());
	}

	return 0;
}
Example #17
0
//! This function reads the SETUP request sent to the default control endpoint
//! and calls the appropriate function. When exiting of the usb_read_request
//! function, the device is ready to manage the next request.
//!
//! If the received request is not supported or a non-standard USB request, the function
//! will call the custom decoding function in usb_specific_request module.
//!
//! @note List of supported requests:
//! GET_DESCRIPTOR
//! GET_CONFIGURATION
//! SET_ADDRESS
//! SET_CONFIGURATION
//! CLEAR_FEATURE
//! SET_FEATURE
//! GET_STATUS
//!
void usb_process_request(void)
{
  U8 bRequest;

  Usb_reset_endpoint_fifo_access(EP_CONTROL);
  bmRequestType = Usb_read_endpoint_data(EP_CONTROL, 8);
  bRequest      = Usb_read_endpoint_data(EP_CONTROL, 8);

  switch (bRequest)
  {
  case GET_DESCRIPTOR:
    if (bmRequestType == 0x80) usb_get_descriptor();
    else goto unsupported_request;
    break;

  case GET_CONFIGURATION:
    if (bmRequestType == 0x80) usb_get_configuration();
    else goto unsupported_request;
    break;

  case SET_ADDRESS:
    if (bmRequestType == 0x00) usb_set_address();
    else goto unsupported_request;
    break;

  case SET_CONFIGURATION:
    if (bmRequestType == 0x00) usb_set_configuration();
    else goto unsupported_request;
    break;

  case CLEAR_FEATURE:
    if (bmRequestType <= 0x02) usb_clear_feature();
    else goto unsupported_request;
    break;

  case SET_FEATURE:
    if (bmRequestType <= 0x02) usb_set_feature();
    else goto unsupported_request;
    break;

  case GET_STATUS:
    if (0x7F < bmRequestType && bmRequestType <= 0x82) usb_get_status();
    else goto unsupported_request;
    break;

  case GET_INTERFACE:
    if (bmRequestType == 0x81)
    {
      if(!usb_get_interface())
      {
        Usb_enable_stall_handshake(EP_CONTROL);
        Usb_ack_setup_received_free();
      }
    }
    else goto unsupported_request;
    break;

  case SET_INTERFACE:
    if (bmRequestType == 0x01) usb_set_interface();
    else goto unsupported_request;
    break;

  case SET_DESCRIPTOR:
  case SYNCH_FRAME:
  default:  //!< unsupported request => call to user read request
unsupported_request:
    if (!usb_user_read_request(bmRequestType, bRequest))
    {
      Usb_enable_stall_handshake(EP_CONTROL);
      Usb_ack_setup_received_free();
    }
    break;
  }
}
Example #18
0
/*
 * WARNING - If a driver calls usb_reset_device, you should simulate a
 * disconnect() and probe() for other interfaces you doesn't claim. This
 * is left up to the driver writer right now. This insures other drivers
 * have a chance to re-setup their interface.
 *
 * Take a look at proc_resetdevice in devio.c for some sample code to
 * do this.
 */
int usb_reset_device(struct usb_device *dev)
{
	struct usb_device *parent = dev->parent;
	struct usb_device_descriptor descriptor;
	int i, ret, port = -1;

    DBG_HOST_HUB("### >>> Enter hub.c file --> usb_reset_device function \n");
	if (!parent) {
		err("attempting to reset root hub!");
		return -EINVAL;
	}

	for (i = 0; i < parent->maxchild; i++)
		if (parent->children[i] == dev) {
			port = i;
			break;
		}

	if (port < 0)
		return -ENOENT;

	down(&usb_address0_sem);

	/* Send a reset to the device */
	if (usb_hub_port_reset(parent, port, dev, HUB_SHORT_RESET_TIME)) {
		usb_hub_port_disable(parent, port);
		up(&usb_address0_sem);
		return(-ENODEV);
	}

	/* Reprogram the Address */
	ret = usb_set_address(dev);
	if (ret < 0) {
		err("USB device not accepting new address (error=%d)", ret);
		usb_hub_port_disable(parent, port);
		up(&usb_address0_sem);
		return ret;
	}

	/* Let the SET_ADDRESS settle */
	wait_ms(10);

	up(&usb_address0_sem);

	/*
	 * Now we fetch the configuration descriptors for the device and
	 * see if anything has changed. If it has, we dump the current
	 * parsed descriptors and reparse from scratch. Then we leave
	 * the device alone for the caller to finish setting up.
	 *
	 * If nothing changed, we reprogram the configuration and then
	 * the alternate settings.
	 */
	ret = usb_get_descriptor(dev, USB_DT_DEVICE, 0, &descriptor,
			sizeof(descriptor));
	if (ret < 0)
		return ret;

	le16_to_cpus(&descriptor.bcdUSB);
	le16_to_cpus(&descriptor.idVendor);
	le16_to_cpus(&descriptor.idProduct);
	le16_to_cpus(&descriptor.bcdDevice);

	if (memcmp(&dev->descriptor, &descriptor, sizeof(descriptor))) {
		usb_destroy_configuration(dev);

		ret = usb_get_device_descriptor(dev);
		if (ret < sizeof(dev->descriptor)) {
			if (ret < 0)
				err("unable to get device descriptor (error=%d)", ret);
			else
				err("USB device descriptor short read (expected %Zi, got %i)", sizeof(dev->descriptor), ret);
        
			clear_bit(dev->devnum, &dev->bus->devmap.devicemap);
			dev->devnum = -1;
			return -EIO;
		}

		ret = usb_get_configuration(dev);
		if (ret < 0) {
			err("unable to get configuration (error=%d)", ret);
			usb_destroy_configuration(dev);
			clear_bit(dev->devnum, &dev->bus->devmap.devicemap);
			dev->devnum = -1;
			return 1;
		}

		dev->actconfig = dev->config;
		usb_set_maxpacket(dev);

		return 1;
	}

	ret = usb_set_configuration(dev, dev->actconfig->bConfigurationValue);
	if (ret < 0) {
		err("failed to set active configuration (error=%d)", ret);
		return ret;
	}

	for (i = 0; i < dev->actconfig->bNumInterfaces; i++) {
		struct usb_interface *intf = &dev->actconfig->interface[i];
		struct usb_interface_descriptor *as = &intf->altsetting[intf->act_altsetting];

		ret = usb_set_interface(dev, as->bInterfaceNumber, as->bAlternateSetting);
		if (ret < 0) {
			err("failed to set active alternate setting for interface %d (error=%d)", i, ret);
			return ret;
		}
	}

	return 0;
}
Example #19
0
int main(int argc, char **argv)
{
	struct usb_vendprod vendprod;
	struct dfu_if _rt_dif, _dif, *dif = &_dif;
	int num_devs;
	int num_ifs;
	unsigned int transfer_size = 0;
	enum mode mode = MODE_NONE;
	struct dfu_status status;
	int quirks_auto_detect = 1;
	dfu_quirks manual_quirks;
	dfu_handle handle;
	char *filename = NULL;
	char *alt_name = NULL; /* query alt name if non-NULL */
	char *end;
	int final_reset = 0;
	int page_size = getpagesize();
	int ret;
	
	printf("dfu-util - (C) 2007-2008 by OpenMoko Inc.\n"
	       "This program is Free Software and has ABSOLUTELY NO WARRANTY\n\n");

	dfu_quirks_clear(&manual_quirks);

	memset(dif, 0, sizeof(*dif));

	usb_init();
	//usb_set_debug(255);
	usb_find_busses();
	usb_find_devices();

	while (1) {
		int c, option_index = 0;
		c = getopt_long(argc, argv, "hVvld:p:c:i:a:t:U:D:C:S:RQNq:", opts,
				&option_index);
		if (c == -1)
			break;

		switch (c) {
		case 'h':
			help();
			exit(0);
			break;
		case 'V':
			print_version();
			exit(0);
			break;
		case 'v':
			verbose = 1;
			break;
		case 'l':
			list_dfu_interfaces();
			exit(0);
			break;
		case 'd':
			/* Parse device */
			if (parse_vendprod(&vendprod, optarg) < 0) {
				fprintf(stderr, "unable to parse `%s'\n", optarg);
				exit(2);
			}
			dif->vendor = vendprod.vendor;
			dif->product = vendprod.product;
			dif->flags |= (DFU_IFF_VENDOR | DFU_IFF_PRODUCT);
			break;
		case 'p':
			/* Parse device path */
			dif->path = optarg;
			dif->flags |= DFU_IFF_PATH;
			ret = resolve_device_path(dif);
			if (ret < 0) {
				fprintf(stderr, "unable to parse `%s'\n",
				    optarg);
				exit(2);
			}
			if (!ret) {
				fprintf(stderr, "cannot find `%s'\n", optarg);
				exit(1);
			}
			break;
		case 'c':
			/* Configuration */
			dif->configuration = atoi(optarg);
			dif->flags |= DFU_IFF_CONFIG;
			break;
		case 'i':
			/* Interface */
			dif->interface = atoi(optarg);
			dif->flags |= DFU_IFF_IFACE;
			break;
		case 'a':
			/* Interface Alternate Setting */
			dif->altsetting = strtoul(optarg, &end, 0);
			if (*end)
				alt_name = optarg;
			dif->flags |= DFU_IFF_ALT;
			break;
		case 't':
			transfer_size = atoi(optarg);
			break;
		case 'U':
			mode = MODE_UPLOAD;
			filename = optarg;
			break;
		case 'D':
			mode = MODE_DOWNLOAD;
			filename = optarg;
			break;
		case 'C':
			mode = MODE_COMPARE;
			/* TODO: verify firmware */
			filename = optarg;
			break;
		case 'S':
			filename = optarg;
			add_file_suffix(filename);
			exit(0);
			break;
		case 'R':
			final_reset = 1;
			break;

		case 'Q':
			dfu_quirks_print();
			exit(0);
			break;
		case 'N':
			quirks_auto_detect = 0;
			break;
		case 'q':
			quirks_auto_detect = 0;
			dfu_quirk_set(&manual_quirks, atoi(optarg));
			break;

		default:
			help();
			exit(2);
		}
	}

	if (mode == MODE_NONE) {
		fprintf(stderr, "You need to specify one of -D or -U\n");
		help();
		exit(2);
	}

	if (!filename) {
		fprintf(stderr, "You need to specify a filename to -D -r -U\n");
		help();
		exit(2);
	}

	dfu_init(&handle, 5000);

	num_devs = count_dfu_devices(dif);
	if (num_devs == 0) {
		fprintf(stderr, "No DFU capable USB device found\n");
		exit(1);
	} else if (num_devs > 1) {
		/* We cannot safely support more than one DFU capable device
		 * with same vendor/product ID, since during DFU we need to do
		 * a USB bus reset, after which the target device will get a
		 * new address */
		fprintf(stderr, "More than one DFU capable USB device found, "
		       "you might try `--list' and then disconnect all but one "
		       "device\n");
		exit(3);
	}
	if (!get_first_dfu_device(dif))
		exit(3);

	/* We have exactly one device. It's usb_device is now in dif->dev */

	printf("Opening USB Device 0x%04x:0x%04x...\n", dif->vendor, dif->product);
	dif->dev_handle = usb_open(dif->dev);
	if (!dif->dev_handle) {
		fprintf(stderr, "Cannot open device: %s\n", usb_strerror());
		exit(1);
	}

	/* try to find first DFU interface of device */
	memcpy(&_rt_dif, dif, sizeof(_rt_dif));
	if (!get_first_dfu_if(&_rt_dif))
		exit(1);

	handle.device = _rt_dif.dev_handle;
	handle.interface = _rt_dif.interface;

	/* automatic quirk detection */
	if(quirks_auto_detect)
	{
		/* TODO: let the detection be influenced by bcdDFU, bcdDevice */
		handle.quirk_flags = dfu_quirks_detect(0, dif->vendor, dif->product, 0);
	}
	/* merge with manual quirks */
	dfu_quirks_insert(&handle.quirk_flags, &manual_quirks);
	if(!dfu_quirks_is_empty(&handle.quirk_flags))
	{
		printf("Selected quirks: ");
		dfu_quirks_print_set(&handle.quirk_flags);
		printf("\n");
	}

	if (!_rt_dif.flags & DFU_IFF_DFU) {
		/* In the 'first round' during runtime mode, there can only be one
	 	* DFU Interface descriptor according to the DFU Spec. */

		/* FIXME: check if the selected device really has only one */

		printf("Claiming USB DFU Runtime Interface %d...\n",
		       _rt_dif.interface);
		if (usb_claim_interface(_rt_dif.dev_handle, _rt_dif.interface) < 0) {
			fprintf(stderr, "Cannot claim interface: %s\n",
				usb_strerror());
			exit(1);
		}

		/* DFU 1.0, Table 4.1: in runtime-mode, alternate
		   interface setting must be zero. therefore we can
		   assume, '0' is correct.

		   the reason we use usb_set_altinterface() here:
		   switch devices to the interface set using
		   usb_claim_interface() above - for some reason this
		   isn't done there.  is the only libusb API which
		   issues the SET_INTERFACE USB standard request is
		   usb_set_altinterface()
		*/
		if (usb_set_altinterface(_rt_dif.dev_handle, 0) < 0) {
			fprintf(stderr, "Cannot set alternate interface %d: %s\n",
				0,
				usb_strerror());
			exit(1);
		}

		printf("Determining device state: ");
		int state = -1;
		if ( (state = dfu_get_state(&handle)) < 0) {
			exit(1);
		}
		printf("state = %s\n", dfu_state_to_string(state));

		dfu_sm_set_state_unchecked(&handle, state);

		printf("Determining device status: ");
		if (dfu_get_status(&handle, &status ) < 0) {
			exit(1);
		}

		printf("state = %s, status = %d = \"%s\"\n",
		       dfu_state_to_string(status.bState),
		       status.bStatus,
		       dfu_status_to_string(status.bStatus) );

		switch (status.bState) {
		case DFU_STATE_appIDLE:
		case DFU_STATE_appDETACH:
			printf("Device really in Runtime Mode, send DFU "
			       "detach request...\n");

			if(status.bState == DFU_STATE_appDETACH) {
				printf("Device is already in state %s, skipping DFU_DETACH request\n",
				       dfu_state_to_string(status.bState));
			}
			else
			{
				if (dfu_detach(&handle, 1000) < 0) {
					exit(1);
					break;
				}
			}

			/* handle bitWillDetach (DFU 1.1) */
			if(handle.dfu_ver == DFU_VERSION_1_1 &&
			   handle.func_dfu.bmAttributes & USB_DFU_WILL_DETACH)
			{
				/* TODO: test this with a real DFU 1.1 device */
				printf("Waiting for USB device's own detach (bitWillDetach=1)...\n");
				dfu_sm_set_state_checked(&handle,
							 DFU_STATE_dfuIDLE);
			}
			else
			{
				printf("Resetting USB...\n");
				ret = dfu_usb_reset(&handle);
				if (ret < 0 && ret != -ENODEV)
				{
					/* do nothing; error msg is output in dfu_usb_reset. */
				}
			}

			sleep(2);
			break;
		case DFU_STATE_dfuERROR:
			printf("dfuERROR, clearing status\n");
			if (dfu_clear_status(&handle) < 0) {
				exit(1);
				break;
			}
			break;
		default:
			fprintf(stderr, "WARNING: Runtime device already "
				"in DFU state ?!?\n");
			goto dfustate;
			break;
		}

		/* now we need to re-scan the bus and locate our device */
		if (usb_find_devices() < 2)
			printf("not at least 2 device changes found ?!?\n");

		if (dif->flags & DFU_IFF_PATH) {
			ret = resolve_device_path(dif);
			if (ret < 0) {
				fprintf(stderr,
				    "internal error: cannot re-parse `%s'\n",
				    dif->path);
				abort();
			}
			if (!ret) {
				fprintf(stderr,
				    "Can't resolve path after RESET?\n");
				exit(1);
			}
		}

		num_devs = count_dfu_devices(dif);
		if (num_devs == 0) {
			fprintf(stderr, "Lost device after RESET?\n");
			exit(1);
		} else if (num_devs > 1) {
			fprintf(stderr, "More than one DFU capable USB "
				"device found, you might try `--list' and "
				"then disconnect all but one device\n");
			exit(1);
		}
		if (!get_first_dfu_device(dif))
			exit(3);

		printf("Opening USB Device...\n");
		dif->dev_handle = usb_open(dif->dev);
		if (!dif->dev_handle) {
			fprintf(stderr, "Cannot open device: %s\n",
				usb_strerror());
			exit(1);
		}
	} else {
		/* we're already in DFU mode, so we can skip the detach/reset
		 * procedure */
	}

 dfustate:
	if (alt_name) {
		int n;

		n = find_dfu_if(dif->dev, &alt_by_name, alt_name);
		if (!n) {
			fprintf(stderr, "No such Alternate Setting: \"%s\"\n",
			    alt_name);
			exit(1);
		}
		if (n < 0) {
			fprintf(stderr, "Error %d in name lookup\n", n);
			exit(1);
		}
		dif->altsetting = n-1;
	}

	print_dfu_if(dif, NULL);

	num_ifs = count_dfu_interfaces(dif->dev);
	if (num_ifs < 0) {
		fprintf(stderr, "No DFU Interface after RESET?!?\n");
		exit(1);
	} else if (num_ifs == 1) {
		if (!get_first_dfu_if(dif)) {
			fprintf(stderr, "Can't find the single available "
				"DFU IF\n");
			exit(1);
		}
	} else if (num_ifs > 1 && (!dif->flags) & (DFU_IFF_IFACE|DFU_IFF_ALT)) {
		fprintf(stderr, "We have %u DFU Interfaces/Altsettings, "
			"you have to specify one via --intf / --alt options\n",
			num_ifs);
		exit(1);
	}

#if 0
	printf("Setting Configuration %u...\n", dif->configuration);
	if (usb_set_configuration(dif->dev_handle, dif->configuration) < 0) {
		fprintf(stderr, "Cannot set configuration: %s\n",
			usb_strerror());
		exit(1);
	}
#endif
	printf("Claiming USB DFU Interface...\n");
	if (usb_claim_interface(dif->dev_handle, dif->interface) < 0) {
		fprintf(stderr, "Cannot claim interface: %s\n",
			usb_strerror());
		exit(1);
	}

	printf("Setting Alternate Setting ...\n");
	if (usb_set_altinterface(dif->dev_handle, dif->altsetting) < 0) {
		fprintf(stderr, "Cannot set alternate interface: %s\n",
			usb_strerror());
		exit(1);
	}

	/* update the handle to point to the dfu-mode descriptor */
	handle.device = dif->dev_handle;
	handle.interface = dif->interface;

 status_again:
	printf("Determining device status: ");
	if (dfu_get_status(&handle, &status ) < 0) {
		fprintf(stderr, "error get_status: %s\n", usb_strerror());
		exit(1);
	}
	printf("state = %s, status = %d\n",
	       dfu_state_to_string(status.bState), status.bStatus);

	/* force the statemachine into current status */
	dfu_sm_set_state_unchecked(&handle, status.bState);

	switch (status.bState) {
	case DFU_STATE_appIDLE:
	case DFU_STATE_appDETACH:
		fprintf(stderr, "Device still in Runtime Mode!\n");
		exit(1);
		break;
	case DFU_STATE_dfuERROR:
		printf("dfuERROR, clearing status\n");
		if (dfu_clear_status(&handle) < 0) {
			fprintf(stderr, "error clear_status: %s\n",
				usb_strerror());
			exit(1);
		}
		goto status_again;
		break;
	case DFU_STATE_dfuDNLOAD_IDLE:
	case DFU_STATE_dfuUPLOAD_IDLE:
		printf("aborting previous incomplete transfer\n");
		if (dfu_abort(&handle) < 0) {
			fprintf(stderr, "can't send DFU_ABORT: %s\n",
				usb_strerror());
			exit(1);
		}
		goto status_again;
		break;
	case DFU_STATE_dfuIDLE:
		printf("dfuIDLE, continuing\n");
		break;
	}

	/* Obtain DFU functional descriptor */
	ret = usb_get_descriptor(dif->dev_handle, 0x21, dif->interface,
				 &(handle.func_dfu), sizeof(handle.func_dfu));
	if (ret < 0) {
		fprintf(stderr, "Error obtaining DFU functional "
			"descriptor: %s\n", usb_strerror());

		if(dfu_quirk_is_set(&handle.quirk_flags,
				    QUIRK_IGNORE_INVALID_FUNCTIONAL_DESCRIPTOR))
		{
			handle.func_dfu.bmAttributes =
				USB_DFU_CAN_DOWNLOAD |
				USB_DFU_CAN_UPLOAD |
				USB_DFU_MANIFEST_TOL;

			handle.func_dfu.wTransferSize = cpu_to_le16(transfer_size);
			if(!transfer_size)
				transfer_size = page_size;

			handle.func_dfu.bcdDFUVersion = USB_DFU_VER_1_0;

			fprintf(stderr, "   Still, try to continue with default flags/manual settings.\n");
		}
		else
		{
			exit(1);
		}
	}
	else
	{
		transfer_size = le16_to_cpu(handle.func_dfu.wTransferSize);
	}

	/* why is this limited to page_size, a host-dependent value? (sgiessl) */
	if (transfer_size > page_size)
		transfer_size = page_size;

	/* quirk overwriting DFU version */
	if(dfu_quirk_is_set(&handle.quirk_flags, QUIRK_FORCE_DFU_VERSION_1_0))
	{
		handle.func_dfu.bcdDFUVersion = USB_DFU_VER_1_0;
	}
	else if(dfu_quirk_is_set(&handle.quirk_flags, QUIRK_FORCE_DFU_VERSION_1_1))
	{
		handle.func_dfu.bcdDFUVersion = USB_DFU_VER_1_1;
	}

	/* read DFU version */
	switch(handle.func_dfu.bcdDFUVersion)
	{
	case USB_DFU_VER_1_1:
		handle.dfu_ver = DFU_VERSION_1_1;
		break;

	default:
		printf("WARNING: device specifies unknown DFU version 0x%.2x, defaulting to DFU 1.0\n",
		       handle.func_dfu.bcdDFUVersion);
		/* fall through intended */
	case USB_DFU_VER_1_0:
		handle.dfu_ver = DFU_VERSION_1_0;
		break;
	}

	printf("Transfer Size = 0x%04x\n", transfer_size);

	printf("Device functional descriptor: %s\n",
	       dfu_func_descriptor_to_string(&handle.func_dfu));

	if (DFU_STATUS_OK != status.bStatus ) {
		printf("WARNING: DFU Status: '%s'\n",
			dfu_status_to_string(status.bStatus));
		/* Clear our status & try again. */
		dfu_clear_status(&handle);
		dfu_get_status(&handle, &status);

		if (DFU_STATUS_OK != status.bStatus) {
			fprintf(stderr, "Error: %d\n", status.bStatus);
			exit(1);
		}
        }

	switch (mode) {
	case MODE_UPLOAD:
		if (sam7dfu_do_upload(&handle,
				  transfer_size, filename) < 0)
			exit(1);
		break;
	case MODE_DOWNLOAD:
		if (sam7dfu_do_dnload(&handle,
				  transfer_size, filename) < 0)
			exit(1);
		break;
	default:
		fprintf(stderr, "Unsupported mode: %u\n", mode);
		exit(1);
	}

	if (final_reset) {
		if(dfu_quirk_is_set(&handle.quirk_flags, QUIRK_OPENMOKO_DETACH_BEFORE_FINAL_RESET))
		{
			/* DFU_DETACH is only allowed in appIDLE, so
			   this is non-standard (as of DFU 1.0, and
			   1.1). */
			printf("Initiating reset by sending DFU_DETACH (QUIRK_OPENMOKO_DETACH_BEFORE_FINAL_RESET)\n");
			if (dfu_detach(&handle, 1000) < 0) {
				fprintf(stderr, "can't detach: %s\n", usb_strerror());
			}
		}
		printf("Resetting USB to switch back to runtime mode\n");
		ret = usb_reset(dif->dev_handle);
		if (ret < 0 && ret != -ENODEV) {
			fprintf(stderr, "error resetting after download: %s\n", 
			usb_strerror());
		}
	}

	exit(0);
}
Example #20
0
static int udl_parse_vendor_descriptor(struct drm_device *dev,
				       struct usb_device *usbdev)
{
	struct udl_device *udl = dev->dev_private;
	char *desc;
	char *buf;
	char *desc_end;

	u8 total_len = 0;

	buf = kzalloc(MAX_VENDOR_DESCRIPTOR_SIZE, GFP_KERNEL);
	if (!buf)
		return false;
	desc = buf;

	total_len = usb_get_descriptor(usbdev, 0x5f, /* vendor specific */
				    0, desc, MAX_VENDOR_DESCRIPTOR_SIZE);
	if (total_len > 5) {
		DRM_INFO("vendor descriptor length:%x data:%11ph\n",
			total_len, desc);

		if ((desc[0] != total_len) || /* descriptor length */
		    (desc[1] != 0x5f) ||   /* vendor descriptor type */
		    (desc[2] != 0x01) ||   /* version (2 bytes) */
		    (desc[3] != 0x00) ||
		    (desc[4] != total_len - 2)) /* length after type */
			goto unrecognized;

		desc_end = desc + total_len;
		desc += 5; /* the fixed header we've already parsed */

		while (desc < desc_end) {
			u8 length;
			u16 key;

			key = le16_to_cpu(*((u16 *) desc));
			desc += sizeof(u16);
			length = *desc;
			desc++;

			switch (key) {
			case 0x0200: { /* max_area */
				u32 max_area;
				max_area = le32_to_cpu(*((u32 *)desc));
				DRM_DEBUG("DL chip limited to %d pixel modes\n",
					max_area);
				udl->sku_pixel_limit = max_area;
				break;
			}
			default:
				break;
			}
			desc += length;
		}
	}

	goto success;

unrecognized:
	/* allow udlfb to load for now even if firmware unrecognized */
	DRM_ERROR("Unrecognized vendor firmware descriptor\n");

success:
	kfree(buf);
	return true;
}
Example #21
0
// hub-only!! ... and only in reset path, or usb_new_device()
// (used by real hubs and virtual root hubs)
int usb_get_configuration(struct usb_device *dev)
{
	int result;
	unsigned int cfgno, length;
	unsigned char *buffer;
	unsigned char *bigbuffer;
 	struct usb_config_descriptor *desc;

	if (dev->descriptor.bNumConfigurations > USB_MAXCONFIG) {
		warn("too many configurations");
		return -EINVAL;
	}

	if (dev->descriptor.bNumConfigurations < 1) {
		warn("not enough configurations");
		return -EINVAL;
	}

	dev->config = (struct usb_host_config *)
		kmalloc(dev->descriptor.bNumConfigurations *
		sizeof(struct usb_host_config), GFP_KERNEL);
	if (!dev->config) {
		err("out of memory");
		return -ENOMEM;	
	}
	memset(dev->config, 0, dev->descriptor.bNumConfigurations *
		sizeof(struct usb_host_config));

	dev->rawdescriptors = (char **)kmalloc(sizeof(char *) *
		dev->descriptor.bNumConfigurations, GFP_KERNEL);
	if (!dev->rawdescriptors) {
		err("out of memory");
		return -ENOMEM;
	}

	buffer = kmalloc(8, GFP_KERNEL);
	if (!buffer) {
		err("unable to allocate memory for configuration descriptors");
		return -ENOMEM;
	}
	desc = (struct usb_config_descriptor *)buffer;

	for (cfgno = 0; cfgno < dev->descriptor.bNumConfigurations; cfgno++) {
		/* We grab the first 8 bytes so we know how long the whole */
		/*  configuration is */
		result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, buffer, 8);
		if (result < 8) {
			if (result < 0)
				err("unable to get descriptor");
			else {
				err("config descriptor too short (expected %i, got %i)", 8, result);
				result = -EINVAL;
			}
			goto err;
		}

  	  	/* Get the full buffer */
		length = le16_to_cpu(desc->wTotalLength);

		bigbuffer = kmalloc(length, GFP_KERNEL);
		if (!bigbuffer) {
			err("unable to allocate memory for configuration descriptors");
			result = -ENOMEM;
			goto err;
		}

		/* Now that we know the length, get the whole thing */
		result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, bigbuffer, length);
		if (result < 0) {
			err("couldn't get all of config descriptors");
			kfree(bigbuffer);
			goto err;
		}	
	
		if (result < length) {
			err("config descriptor too short (expected %i, got %i)", length, result);
			result = -EINVAL;
			kfree(bigbuffer);
			goto err;
		}

		dev->rawdescriptors[cfgno] = bigbuffer;

		result = usb_parse_configuration(&dev->config[cfgno], bigbuffer);
		if (result > 0)
			dbg("descriptor data left");
		else if (result < 0) {
			result = -EINVAL;
			goto err;
		}
	}

	kfree(buffer);
	return 0;
err:
	kfree(buffer);
	dev->descriptor.bNumConfigurations = cfgno;
	return result;
}
//! @brief This function reads the SETUP request sent to the default control endpoint
//! and calls the appropriate function. When exiting of the usb_read_request
//! function, the device is ready to manage the next request.
//!
void usb_process_request(void)
{
   U8 bmRequestType;
   U8 bmRequest;

   Usb_ack_control_out();
   bmRequestType = Usb_read_byte();
   bmRequest     = Usb_read_byte();

   switch (bmRequest)
   {
      case SETUP_GET_DESCRIPTOR:
      if (USB_SETUP_GET_STAND_DEVICE == bmRequestType)
      {     
         if( usb_get_descriptor() )
            return;
      }
      break;

      case SETUP_GET_CONFIGURATION:
      if (USB_SETUP_GET_STAND_DEVICE == bmRequestType)
      {
         usb_get_configuration();
         return;
      }
      break;

      case SETUP_SET_ADDRESS:
      if (USB_SETUP_SET_STAND_DEVICE == bmRequestType)
      {
         usb_set_address();
         return;
      }
      break;

      case SETUP_SET_CONFIGURATION:
      if (USB_SETUP_SET_STAND_DEVICE == bmRequestType)
      { 
         if( usb_set_configuration() )
            return;
      }
      break;

      case SETUP_CLEAR_FEATURE:
      if (usb_clear_feature(bmRequestType))
         return;
      break;

      case SETUP_SET_FEATURE:
      if (usb_set_feature(bmRequestType))
         return;
      break;

      case SETUP_GET_STATUS:
      if (usb_get_status(bmRequestType))
         return;
      break;

      case SETUP_GET_INTERFACE:
      if (USB_SETUP_GET_STAND_INTERFACE == bmRequestType)
      {
         if( usb_get_interface() )
            return;
      }
      break;

      case SETUP_SET_INTERFACE:
      if (bmRequestType == USB_SETUP_SET_STAND_INTERFACE)
      {
         if( usb_set_interface() )
            return;
      }
      break;

      default:
      break;
   }

   // un-supported like standard request => call to user read request
   if( !usb_user_read_request(bmRequestType, bmRequest) )
   {
      // Request unknow in the specific request list from interface
      // keep that order (set StallRq/clear RxSetup) or a
      // OUT request following the SETUP may be acknowledged
      Usb_enable_stall_handshake();
      Usb_ack_receive_setup();
      endpoint_status[(EP_CONTROL & MSK_EP_DIR)] = 0x01;
   }
}
Example #23
0
// hub-only!! ... and only in reset path, or usb_new_device()
// (used by real hubs and virtual root hubs)
int usb_get_configuration(struct usb_device *dev)
{
	struct device *ddev = &dev->dev;
	int ncfg = dev->descriptor.bNumConfigurations;
	int result = -ENOMEM;
	unsigned int cfgno, length;
	unsigned char *buffer;
	unsigned char *bigbuffer;
 	struct usb_config_descriptor *desc;

	if (ncfg > USB_MAXCONFIG) {
		dev_warn(ddev, "too many configurations: %d, "
		    "using maximum allowed: %d\n", ncfg, USB_MAXCONFIG);
		dev->descriptor.bNumConfigurations = ncfg = USB_MAXCONFIG;
	}

	if (ncfg < 1) {
#if 0 
		dev_err(ddev, "no configurations\n");
		return -EINVAL;
#else
		
		dev_err(ddev, "no configurations, try to get configurations [cfyeh]\n");
		ncfg = 1;
#endif
	}

	length = ncfg * sizeof(struct usb_host_config);
	dev->config = kmalloc(length, GFP_KERNEL);
	if (!dev->config)
		goto err2;
	memset(dev->config, 0, length);

	length = ncfg * sizeof(char *);
	dev->rawdescriptors = kmalloc(length, GFP_KERNEL);
	if (!dev->rawdescriptors)
		goto err2;
	memset(dev->rawdescriptors, 0, length);

#ifdef USB_512B_ALIGNMENT
	buffer = kmalloc(USB_512B_ALIGNMENT_SIZE, GFP_KERNEL);
#else
	buffer = kmalloc(USB_DT_CONFIG_SIZE, GFP_KERNEL);
#endif /* USB_512B_ALIGNMENT */
	if (!buffer)
		goto err2;
	desc = (struct usb_config_descriptor *)buffer;

	for (cfgno = 0; cfgno < ncfg; cfgno++) {
		/* We grab just the first descriptor so we know how long
		 * the whole configuration is */
		result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno,
		    buffer, USB_DT_CONFIG_SIZE);
		if (result < 0) {
			dev_err(ddev, "unable to read config index %d "
			    "descriptor/%s\n", cfgno, "start");
			goto err;
		} else if (result < 4) {
			dev_err(ddev, "config index %d descriptor too short "
			    "(expected %i, got %i)\n", cfgno,
			    USB_DT_CONFIG_SIZE, result);
			result = -EINVAL;
			goto err;
		}
		length = max((int) le16_to_cpu(desc->wTotalLength),
		    USB_DT_CONFIG_SIZE);

		/* Now that we know the length, get the whole thing */
#ifdef USB_512B_ALIGNMENT
		if(length > USB_512B_ALIGNMENT_SIZE)
			bigbuffer = kmalloc(length, GFP_KERNEL);
		else
			bigbuffer = kmalloc(USB_512B_ALIGNMENT_SIZE, GFP_KERNEL);
#else
		bigbuffer = kmalloc(length, GFP_KERNEL);
#endif /* USB_512B_ALIGNMENT */
		if (!bigbuffer) {
			result = -ENOMEM;
			goto err;
		}
		result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno,
		    bigbuffer, length);
		if (result < 0) {
			dev_err(ddev, "unable to read config index %d "
			    "descriptor/%s\n", cfgno, "all");
			kfree(bigbuffer);
			goto err;
		}
		if (result < length) {
			dev_warn(ddev, "config index %d descriptor too short "
			    "(expected %i, got %i)\n", cfgno, length, result);
			length = result;
		}

		dev->rawdescriptors[cfgno] = bigbuffer;

		result = usb_parse_configuration(&dev->dev, cfgno,
		    &dev->config[cfgno], bigbuffer, length);
		if (result < 0) {
			++cfgno;
			goto err;
		}
	}
	result = 0;

err:
	kfree(buffer);
	dev->descriptor.bNumConfigurations = cfgno;
err2:
	if (result == -ENOMEM)
		dev_err(ddev, "out of memory\n");
	return result;
}
static int udl_parse_vendor_descriptor(struct drm_device *dev,
				       struct usb_device *usbdev)
{
	struct udl_device *udl = dev->dev_private;
	char *desc;
	char *buf;
	char *desc_end;

	u8 total_len = 0;

	buf = kzalloc(MAX_VENDOR_DESCRIPTOR_SIZE, GFP_KERNEL);
	if (!buf)
		return false;
	desc = buf;

	total_len = usb_get_descriptor(usbdev, 0x5f, 
				    0, desc, MAX_VENDOR_DESCRIPTOR_SIZE);
	if (total_len > 5) {
		DRM_INFO("vendor descriptor length:%x data:%02x %02x %02x %02x" \
			"%02x %02x %02x %02x %02x %02x %02x\n",
			total_len, desc[0],
			desc[1], desc[2], desc[3], desc[4], desc[5], desc[6],
			desc[7], desc[8], desc[9], desc[10]);

		if ((desc[0] != total_len) || 
		    (desc[1] != 0x5f) ||   
		    (desc[2] != 0x01) ||   
		    (desc[3] != 0x00) ||
		    (desc[4] != total_len - 2)) 
			goto unrecognized;

		desc_end = desc + total_len;
		desc += 5; 

		while (desc < desc_end) {
			u8 length;
			u16 key;

			key = *((u16 *) desc);
			desc += sizeof(u16);
			length = *desc;
			desc++;

			switch (key) {
			case 0x0200: { 
				u32 max_area;
				max_area = le32_to_cpu(*((u32 *)desc));
				DRM_DEBUG("DL chip limited to %d pixel modes\n",
					max_area);
				udl->sku_pixel_limit = max_area;
				break;
			}
			default:
				break;
			}
			desc += length;
		}
	}

	goto success;

unrecognized:
	
	DRM_ERROR("Unrecognized vendor firmware descriptor\n");

success:
	kfree(buf);
	return true;
}
Example #25
0
/* FIXME: prototype for adding security */
int wusb_dev_sec_add(struct wusbhc *wusbhc,
		     struct usb_device *usb_dev, struct wusb_dev *wusb_dev)
{
	int result, bytes, secd_size;
	struct device *dev = &usb_dev->dev;
	struct usb_security_descriptor *secd;
	const struct usb_encryption_descriptor *etd, *ccm1_etd = NULL;
	const void *itr, *top;
	char buf[64];

	secd = kmalloc(sizeof(*secd), GFP_KERNEL);
	if (secd == NULL) {
		result = -ENOMEM;
		goto out;
	}

	result = usb_get_descriptor(usb_dev, USB_DT_SECURITY,
				    0, secd, sizeof(*secd));
	if (result < sizeof(*secd)) {
		dev_err(dev, "Can't read security descriptor or "
			"not enough data: %d\n", result);
		goto out;
	}
	secd_size = le16_to_cpu(secd->wTotalLength);
	secd = krealloc(secd, secd_size, GFP_KERNEL);
	if (secd == NULL) {
		dev_err(dev, "Can't allocate space for security descriptors\n");
		goto out;
	}
	result = usb_get_descriptor(usb_dev, USB_DT_SECURITY,
				    0, secd, secd_size);
	if (result < secd_size) {
		dev_err(dev, "Can't read security descriptor or "
			"not enough data: %d\n", result);
		goto out;
	}
	bytes = 0;
	itr = &secd[1];
	top = (void *)secd + result;
	while (itr < top) {
		etd = itr;
		if (top - itr < sizeof(*etd)) {
			dev_err(dev, "BUG: bad device security descriptor; "
				"not enough data (%zu vs %zu bytes left)\n",
				top - itr, sizeof(*etd));
			break;
		}
		if (etd->bLength < sizeof(*etd)) {
			dev_err(dev, "BUG: bad device encryption descriptor; "
				"descriptor is too short "
				"(%u vs %zu needed)\n",
				etd->bLength, sizeof(*etd));
			break;
		}
		itr += etd->bLength;
		bytes += snprintf(buf + bytes, sizeof(buf) - bytes,
				  "%s (0x%02x/%02x) ",
				  wusb_et_name(etd->bEncryptionType),
				  etd->bEncryptionValue, etd->bAuthKeyIndex);
		if (etd->bEncryptionType == USB_ENC_TYPE_CCM_1)
			ccm1_etd = etd;
	}
	/* This code only supports CCM1 as of now. */
	/* FIXME: user has to choose which sec mode to use?
	 * In theory we want CCM */
	if (ccm1_etd == NULL) {
		dev_err(dev, "WUSB device doesn't support CCM1 encryption, "
			"can't use!\n");
		result = -EINVAL;
		goto out;
	}
	wusb_dev->ccm1_etd = *ccm1_etd;
	dev_dbg(dev, "supported encryption: %s; using %s (0x%02x/%02x)\n",
		buf, wusb_et_name(ccm1_etd->bEncryptionType),
		ccm1_etd->bEncryptionValue, ccm1_etd->bAuthKeyIndex);
	result = 0;
out:
	kfree(secd);
	return result;
}
Example #26
0
//! usb_process_request.
//!
//! @brief This function reads the SETUP request sent to the default control endpoint
//! and calls the appropriate function. When exiting of the usb_read_request
//! function, the device is ready to manage the next request.
//!
//! @param none
//!
//! @return none
//! @note list of supported requests:
//! GET_DESCRIPTOR
//! GET_CONFIGURATION
//! SET_ADDRESS
//! SET_CONFIGURATION
//! CLEAR_FEATURE
//! SET_FEATURE
//! GET_STATUS
//!
void usb_process_request(void)
{
   U8  bmRequest;

   bmRequestType = Usb_read_byte();
   bmRequest     = Usb_read_byte();

   switch (bmRequest)
   {
    case GET_DESCRIPTOR:
         if (0x80 == bmRequestType) { usb_get_descriptor(); }
         else                       { usb_user_read_request(bmRequestType, bmRequest); }
         break;

    case GET_CONFIGURATION:
         if (0x80 == bmRequestType) { usb_get_configuration(); }
         else                       { usb_user_read_request(bmRequestType, bmRequest); }
         break;

    case SET_ADDRESS:
         if (0x00 == bmRequestType) { usb_set_address(); }
         else                       { usb_user_read_request(bmRequestType, bmRequest); }
         break;

    case SET_CONFIGURATION:
         if (0x00 == bmRequestType) { usb_set_configuration(); }
         else                       { usb_user_read_request(bmRequestType, bmRequest); }
         break;

    case CLEAR_FEATURE:
         if (0x02 >= bmRequestType) { usb_clear_feature(); }
         else                       { usb_user_read_request(bmRequestType, bmRequest); }
         break;

    case SET_FEATURE:
         if (0x02 >= bmRequestType) { usb_set_feature(); }
         else                       { usb_user_read_request(bmRequestType, bmRequest); }
         break;

    case GET_STATUS:
         if ((0x7F < bmRequestType) & (0x82 >= bmRequestType))
                                    { usb_get_status(); }
         else                       { usb_user_read_request(bmRequestType, bmRequest); }
         break;

    case GET_INTERFACE:
          if (bmRequestType == 0x81) { usb_get_interface(); }
          else { usb_user_read_request(bmRequestType, bmRequest); }
          break;


    case SET_INTERFACE:
      if (bmRequestType == 0x01) {usb_set_interface();}
      break;

    case SET_DESCRIPTOR:
    case SYNCH_FRAME:
    default: //!< un-supported request => call to user read request
         if(usb_user_read_request(bmRequestType, bmRequest) == FALSE)
         {
            Usb_enable_stall_handshake();
            Usb_ack_receive_setup();
            return;
         }
         break;
  }
}
int main(int argc, char **argv) {
    int ret, vendor, product;
    struct usb_device *dev;
    char buf[65535], *endptr;
#if 0
    usb_urb *isourb;
    struct timeval isotv;
    char isobuf[32768];
#endif

    usb_init();
//    usb_set_debug(255);
    usb_find_busses();
    usb_find_devices();
/*
    if (argc!=3) {
	printf("usage: %s vendorID productID\n", argv[0]);
	printf("ID numbers of currently attached devices:\n");
	list_devices();
	exit(1);
    }
    vendor = strtol(argv[1], &endptr, 16);
    if (*endptr != '\0') {
	printf("invalid vendor id\n");
	exit(1);
    }
    product = strtol(argv[2], &endptr, 16);
    if (*endptr != '\0') {
	printf("invalid product id\n");
	exit(1);
    }
*/
    printf("Hladam HUAWEI E220 a prepnem na modem - bbo 06\n");
    vendor = 0x12d1;
    product = 0x1003;
    dev = find_device(vendor, product);
    assert(dev);

    devh = usb_open(dev);
    assert(devh);
    
    signal(SIGTERM, release_usb_device);

/*
    ret = usb_get_driver_np(devh, 0, buf, sizeof(buf));
    printf("usb_get_driver_np returned %d\n", ret);
    if (ret == 0) {
	printf("interface 0 already claimed by driver \"%s\", attempting to detach it\n", buf);
	ret = usb_detach_kernel_driver_np(devh, 0);
	printf("usb_detach_kernel_driver_np returned %d\n", ret);
    }
    ret = usb_claim_interface(devh, 0);
    if (ret != 0) {
	printf("claim failed with error %d\n", ret);
		exit(1);
    }
    
    ret = usb_set_altinterface(devh, 0);
    assert(ret >= 0);
*/
// BBO typ 1 = DEVICE
ret = usb_get_descriptor(devh, 0x0000001, 0x0000000, buf, 0x0000012);
//printf("1 get descriptor returned %d, bytes: ", ret);
//print_bytes(buf, ret);
//printf("\n");
usleep(1*1000);
// BBO typ 2 = CONFIGURATION
ret = usb_get_descriptor(devh, 0x0000002, 0x0000000, buf, 0x0000009);
//printf("2 get descriptor returned %d, bytes: ", ret);
//print_bytes(buf, ret);
//printf("\n");
usleep(1*1000);
// BBO typ 2 = CONFIGURATION
ret = usb_get_descriptor(devh, 0x0000002, 0x0000000, buf, 0x0000020);
//printf("3 get descriptor returned %d, bytes: ", ret);
//print_bytes(buf, ret);
//printf("\n");
usleep(1*1000);
/*
ret = usb_release_interface(devh, 0);
if (ret != 0) printf("failed to release interface before set_configuration: %d\n", ret);
ret = usb_set_configuration(devh, 0x0000001);
printf("4 set configuration returned %d\n", ret);
ret = usb_claim_interface(devh, 0);
if (ret != 0) printf("claim after set_configuration failed with error %d\n", ret);
ret = usb_set_altinterface(devh, 0);
printf("4 set alternate setting returned %d\n", ret);
usleep(50*1000);
ret = usb_set_altinterface(devh, 0);
printf("5 set alternate setting returned %d\n", ret);
usleep(62*1000);
*/
ret = usb_control_msg(devh, USB_TYPE_STANDARD + USB_RECIP_DEVICE, USB_REQ_SET_FEATURE, 00000001, 0, buf, 0, 1000);
printf("4 set feature request returned %d\n", ret);
/*
	ret = usb_release_interface(devh, 0);
	assert(ret == 0);
*/
	ret = usb_close(devh);
	assert(ret == 0);
	printf("Prepnute-OK, Mas ttyUSB0 ttyUSB1 (cez usbserial vendor=0x12d1 product=0x1004)\n");
	printf("pozri /proc/bus/usb/devices\n");
	return 0;
}
Example #28
0
static int ch9_postconfig(struct usbtest_dev *dev)
{
	struct usb_interface	*iface = dev->intf;
	struct usb_device	*udev = interface_to_usbdev(iface);
	int			i, alt, retval;

	for (i = 0; i < iface->num_altsetting; i++) {

		
		alt = iface->altsetting[i].desc.bAlternateSetting;
		if (alt < 0 || alt >= iface->num_altsetting) {
			dev_err(&iface->dev,
					"invalid alt [%d].bAltSetting = %d\n",
					i, alt);
		}

		
		if (realworld && iface->num_altsetting == 1)
			continue;

		
		retval = set_altsetting(dev, alt);
		if (retval) {
			dev_err(&iface->dev, "can't set_interface = %d, %d\n",
					alt, retval);
			return retval;
		}

		
		retval = get_altsetting(dev);
		if (retval != alt) {
			dev_err(&iface->dev, "get alt should be %d, was %d\n",
					alt, retval);
			return (retval < 0) ? retval : -EDOM;
		}

	}

	
	if (!realworld || udev->descriptor.bNumConfigurations != 1) {
		int	expected = udev->actconfig->desc.bConfigurationValue;

		retval = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
				USB_REQ_GET_CONFIGURATION,
				USB_DIR_IN | USB_RECIP_DEVICE,
				0, 0, dev->buf, 1, USB_CTRL_GET_TIMEOUT);
		if (retval != 1 || dev->buf[0] != expected) {
			dev_err(&iface->dev, "get config --> %d %d (1 %d)\n",
				retval, dev->buf[0], expected);
			return (retval < 0) ? retval : -EDOM;
		}
	}

	
	retval = usb_get_descriptor(udev, USB_DT_DEVICE, 0,
			dev->buf, sizeof udev->descriptor);
	if (retval != sizeof udev->descriptor) {
		dev_err(&iface->dev, "dev descriptor --> %d\n", retval);
		return (retval < 0) ? retval : -EDOM;
	}

	
	for (i = 0; i < udev->descriptor.bNumConfigurations; i++) {
		retval = usb_get_descriptor(udev, USB_DT_CONFIG, i,
				dev->buf, TBUF_SIZE);
		if (!is_good_config(dev, retval)) {
			dev_err(&iface->dev,
					"config [%d] descriptor --> %d\n",
					i, retval);
			return (retval < 0) ? retval : -EDOM;
		}

	}

	
	if (le16_to_cpu(udev->descriptor.bcdUSB) == 0x0200) {
		struct usb_qualifier_descriptor *d = NULL;

		
		retval = usb_get_descriptor(udev,
				USB_DT_DEVICE_QUALIFIER, 0, dev->buf,
				sizeof(struct usb_qualifier_descriptor));
		if (retval == -EPIPE) {
			if (udev->speed == USB_SPEED_HIGH) {
				dev_err(&iface->dev,
						"hs dev qualifier --> %d\n",
						retval);
				return (retval < 0) ? retval : -EDOM;
			}
			
		} else if (retval != sizeof(struct usb_qualifier_descriptor)) {
			dev_err(&iface->dev, "dev qualifier --> %d\n", retval);
			return (retval < 0) ? retval : -EDOM;
		} else
			d = (struct usb_qualifier_descriptor *) dev->buf;

		
		if (d) {
			unsigned max = d->bNumConfigurations;
			for (i = 0; i < max; i++) {
				retval = usb_get_descriptor(udev,
					USB_DT_OTHER_SPEED_CONFIG, i,
					dev->buf, TBUF_SIZE);
				if (!is_good_config(dev, retval)) {
					dev_err(&iface->dev,
						"other speed config --> %d\n",
						retval);
					return (retval < 0) ? retval : -EDOM;
				}
			}
		}
	}
	

	
	retval = usb_get_status(udev, USB_RECIP_DEVICE, 0, dev->buf);
	if (retval != 2) {
		dev_err(&iface->dev, "get dev status --> %d\n", retval);
		return (retval < 0) ? retval : -EDOM;
	}


	retval = usb_get_status(udev, USB_RECIP_INTERFACE,
			iface->altsetting[0].desc.bInterfaceNumber, dev->buf);
	if (retval != 2) {
		dev_err(&iface->dev, "get interface status --> %d\n", retval);
		return (retval < 0) ? retval : -EDOM;
	}
	

	return 0;
}