|  | @@ -900,76 +900,155 @@ int usb_get_string_descriptor ( struct usb_device *usb, unsigned int index,
 | 
		
	
		
			
			| 900 | 900 |   ******************************************************************************
 | 
		
	
		
			
			| 901 | 901 |   */
 | 
		
	
		
			
			| 902 | 902 |  
 | 
		
	
		
			
			|  | 903 | +/**
 | 
		
	
		
			
			|  | 904 | + * Get USB configuration descriptor
 | 
		
	
		
			
			|  | 905 | + *
 | 
		
	
		
			
			|  | 906 | + * @v usb		USB device
 | 
		
	
		
			
			|  | 907 | + * @v index		Configuration index
 | 
		
	
		
			
			|  | 908 | + * @ret config		Configuration descriptor
 | 
		
	
		
			
			|  | 909 | + * @ret rc		Return status code
 | 
		
	
		
			
			|  | 910 | + *
 | 
		
	
		
			
			|  | 911 | + * The configuration descriptor is dynamically allocated and must
 | 
		
	
		
			
			|  | 912 | + * eventually be freed by the caller.
 | 
		
	
		
			
			|  | 913 | + */
 | 
		
	
		
			
			|  | 914 | +static int
 | 
		
	
		
			
			|  | 915 | +usb_config_descriptor ( struct usb_device *usb, unsigned int index,
 | 
		
	
		
			
			|  | 916 | +			struct usb_configuration_descriptor **config ) {
 | 
		
	
		
			
			|  | 917 | +	struct usb_configuration_descriptor partial;
 | 
		
	
		
			
			|  | 918 | +	size_t len;
 | 
		
	
		
			
			|  | 919 | +	int rc;
 | 
		
	
		
			
			|  | 920 | +
 | 
		
	
		
			
			|  | 921 | +	/* Read first part of configuration descriptor to get size */
 | 
		
	
		
			
			|  | 922 | +	if ( ( rc = usb_get_config_descriptor ( usb, index, &partial,
 | 
		
	
		
			
			|  | 923 | +						sizeof ( partial ) ) ) != 0 ) {
 | 
		
	
		
			
			|  | 924 | +		DBGC ( usb, "USB %s could not get configuration descriptor %d: "
 | 
		
	
		
			
			|  | 925 | +		       "%s\n", usb->name, index, strerror ( rc ) );
 | 
		
	
		
			
			|  | 926 | +		goto err_get_partial;
 | 
		
	
		
			
			|  | 927 | +	}
 | 
		
	
		
			
			|  | 928 | +	len = le16_to_cpu ( partial.len );
 | 
		
	
		
			
			|  | 929 | +	if ( len < sizeof ( partial ) ) {
 | 
		
	
		
			
			|  | 930 | +		DBGC ( usb, "USB %s underlength configuraton descriptor %d\n",
 | 
		
	
		
			
			|  | 931 | +		       usb->name, index );
 | 
		
	
		
			
			|  | 932 | +		rc = -EINVAL;
 | 
		
	
		
			
			|  | 933 | +		goto err_partial_len;
 | 
		
	
		
			
			|  | 934 | +	}
 | 
		
	
		
			
			|  | 935 | +
 | 
		
	
		
			
			|  | 936 | +	/* Allocate buffer for whole configuration descriptor */
 | 
		
	
		
			
			|  | 937 | +	*config = malloc ( len );
 | 
		
	
		
			
			|  | 938 | +	if ( ! *config ) {
 | 
		
	
		
			
			|  | 939 | +		rc = -ENOMEM;
 | 
		
	
		
			
			|  | 940 | +		goto err_alloc_config;
 | 
		
	
		
			
			|  | 941 | +	}
 | 
		
	
		
			
			|  | 942 | +
 | 
		
	
		
			
			|  | 943 | +	/* Read whole configuration descriptor */
 | 
		
	
		
			
			|  | 944 | +	if ( ( rc = usb_get_config_descriptor ( usb, index, *config,
 | 
		
	
		
			
			|  | 945 | +						len ) ) != 0 ) {
 | 
		
	
		
			
			|  | 946 | +		DBGC ( usb, "USB %s could not get configuration descriptor %d: "
 | 
		
	
		
			
			|  | 947 | +		       "%s\n", usb->name, index, strerror ( rc ) );
 | 
		
	
		
			
			|  | 948 | +		goto err_get_config_descriptor;
 | 
		
	
		
			
			|  | 949 | +	}
 | 
		
	
		
			
			|  | 950 | +	if ( (*config)->len != partial.len ) {
 | 
		
	
		
			
			|  | 951 | +		DBGC ( usb, "USB %s bad configuration descriptor %d length\n",
 | 
		
	
		
			
			|  | 952 | +		       usb->name, index );
 | 
		
	
		
			
			|  | 953 | +		rc = -EINVAL;
 | 
		
	
		
			
			|  | 954 | +		goto err_config_len;
 | 
		
	
		
			
			|  | 955 | +	}
 | 
		
	
		
			
			|  | 956 | +
 | 
		
	
		
			
			|  | 957 | +	return 0;
 | 
		
	
		
			
			|  | 958 | +
 | 
		
	
		
			
			|  | 959 | + err_config_len:
 | 
		
	
		
			
			|  | 960 | + err_get_config_descriptor:
 | 
		
	
		
			
			|  | 961 | +	free ( *config );
 | 
		
	
		
			
			|  | 962 | + err_alloc_config:
 | 
		
	
		
			
			|  | 963 | + err_partial_len:
 | 
		
	
		
			
			|  | 964 | + err_get_partial:
 | 
		
	
		
			
			|  | 965 | +	return rc;
 | 
		
	
		
			
			|  | 966 | +}
 | 
		
	
		
			
			|  | 967 | +
 | 
		
	
		
			
			| 903 | 968 |  /**
 | 
		
	
		
			
			| 904 | 969 |   * Describe USB function
 | 
		
	
		
			
			| 905 | 970 |   *
 | 
		
	
		
			
			| 906 |  | - * @v func		USB function
 | 
		
	
		
			
			|  | 971 | + * @v usb		USB device
 | 
		
	
		
			
			| 907 | 972 |   * @v config		Configuration descriptor
 | 
		
	
		
			
			| 908 | 973 |   * @v first		First interface number
 | 
		
	
		
			
			|  | 974 | + * @v interfaces	Interface list to fill in
 | 
		
	
		
			
			|  | 975 | + * @v desc		Function descriptor to fill in
 | 
		
	
		
			
			| 909 | 976 |   * @ret rc		Return status code
 | 
		
	
		
			
			| 910 | 977 |   */
 | 
		
	
		
			
			| 911 |  | -static int usb_function ( struct usb_function *func,
 | 
		
	
		
			
			|  | 978 | +static int usb_describe ( struct usb_device *usb,
 | 
		
	
		
			
			| 912 | 979 |  			  struct usb_configuration_descriptor *config,
 | 
		
	
		
			
			| 913 |  | -			  unsigned int first ) {
 | 
		
	
		
			
			| 914 |  | -	struct usb_device *usb = func->usb;
 | 
		
	
		
			
			|  | 980 | +			  unsigned int first, uint8_t *interfaces,
 | 
		
	
		
			
			|  | 981 | +			  struct usb_function_descriptor *desc ) {
 | 
		
	
		
			
			| 915 | 982 |  	struct usb_interface_association_descriptor *association;
 | 
		
	
		
			
			| 916 | 983 |  	struct usb_interface_descriptor *interface;
 | 
		
	
		
			
			| 917 | 984 |  	struct cdc_union_descriptor *cdc_union;
 | 
		
	
		
			
			| 918 | 985 |  	unsigned int i;
 | 
		
	
		
			
			| 919 | 986 |  
 | 
		
	
		
			
			|  | 987 | +	/* Fill in vendor and product ID */
 | 
		
	
		
			
			|  | 988 | +	desc->vendor = le16_to_cpu ( usb->device.vendor );
 | 
		
	
		
			
			|  | 989 | +	desc->product = le16_to_cpu ( usb->device.product );
 | 
		
	
		
			
			|  | 990 | +
 | 
		
	
		
			
			| 920 | 991 |  	/* First, look for an interface association descriptor */
 | 
		
	
		
			
			| 921 | 992 |  	association = usb_interface_association_descriptor ( config, first );
 | 
		
	
		
			
			| 922 | 993 |  	if ( association ) {
 | 
		
	
		
			
			| 923 | 994 |  
 | 
		
	
		
			
			| 924 | 995 |  		/* Sanity check */
 | 
		
	
		
			
			| 925 |  | -		if ( association->count > config->interfaces ) {
 | 
		
	
		
			
			|  | 996 | +		assert ( association->first == first );
 | 
		
	
		
			
			|  | 997 | +		if ( ( first + association->count ) > config->interfaces ) {
 | 
		
	
		
			
			| 926 | 998 |  			DBGC ( usb, "USB %s has invalid association [%d-%d)\n",
 | 
		
	
		
			
			| 927 |  | -			       func->name, association->first,
 | 
		
	
		
			
			| 928 |  | -			       ( association->first + association->count ) );
 | 
		
	
		
			
			|  | 999 | +			       usb->name, first, ( first + association->count));
 | 
		
	
		
			
			| 929 | 1000 |  			return -ERANGE;
 | 
		
	
		
			
			| 930 | 1001 |  		}
 | 
		
	
		
			
			| 931 | 1002 |  
 | 
		
	
		
			
			| 932 | 1003 |  		/* Describe function */
 | 
		
	
		
			
			| 933 |  | -		memcpy ( &func->class, &association->class,
 | 
		
	
		
			
			| 934 |  | -			 sizeof ( func->class ) );
 | 
		
	
		
			
			| 935 |  | -		func->count = association->count;
 | 
		
	
		
			
			|  | 1004 | +		memcpy ( &desc->class, &association->class,
 | 
		
	
		
			
			|  | 1005 | +			 sizeof ( desc->class ) );
 | 
		
	
		
			
			|  | 1006 | +		desc->count = association->count;
 | 
		
	
		
			
			| 936 | 1007 |  		for ( i = 0 ; i < association->count ; i++ )
 | 
		
	
		
			
			| 937 |  | -			func->interface[i] = ( association->first + i );
 | 
		
	
		
			
			|  | 1008 | +			interfaces[i] = ( first + i );
 | 
		
	
		
			
			| 938 | 1009 |  		return 0;
 | 
		
	
		
			
			| 939 | 1010 |  	}
 | 
		
	
		
			
			| 940 | 1011 |  
 | 
		
	
		
			
			| 941 | 1012 |  	/* Next, look for an interface descriptor */
 | 
		
	
		
			
			| 942 | 1013 |  	interface = usb_interface_descriptor ( config, first, 0 );
 | 
		
	
		
			
			| 943 | 1014 |  	if ( ! interface ) {
 | 
		
	
		
			
			| 944 |  | -		DBGC ( usb, "USB %s has no interface descriptor\n",
 | 
		
	
		
			
			| 945 |  | -		       func->name );
 | 
		
	
		
			
			|  | 1015 | +		DBGC ( usb, "USB %s has no descriptor for interface %d\n",
 | 
		
	
		
			
			|  | 1016 | +		       usb->name, first );
 | 
		
	
		
			
			| 946 | 1017 |  		return -ENOENT;
 | 
		
	
		
			
			| 947 | 1018 |  	}
 | 
		
	
		
			
			| 948 | 1019 |  
 | 
		
	
		
			
			| 949 | 1020 |  	/* Describe function */
 | 
		
	
		
			
			| 950 |  | -	memcpy ( &func->class, &interface->class, sizeof ( func->class ) );
 | 
		
	
		
			
			| 951 |  | -	func->count = 1;
 | 
		
	
		
			
			| 952 |  | -	func->interface[0] = first;
 | 
		
	
		
			
			|  | 1021 | +	memcpy ( &desc->class, &interface->class, sizeof ( desc->class ) );
 | 
		
	
		
			
			|  | 1022 | +	desc->count = 1;
 | 
		
	
		
			
			|  | 1023 | +	interfaces[0] = first;
 | 
		
	
		
			
			| 953 | 1024 |  
 | 
		
	
		
			
			| 954 | 1025 |  	/* Look for a CDC union descriptor, if applicable */
 | 
		
	
		
			
			| 955 |  | -	if ( ( func->class.class == USB_CLASS_CDC ) &&
 | 
		
	
		
			
			|  | 1026 | +	if ( ( desc->class.class == USB_CLASS_CDC ) &&
 | 
		
	
		
			
			| 956 | 1027 |  	     ( cdc_union = cdc_union_descriptor ( config, interface ) ) ) {
 | 
		
	
		
			
			| 957 | 1028 |  
 | 
		
	
		
			
			| 958 | 1029 |  		/* Determine interface count */
 | 
		
	
		
			
			| 959 |  | -		func->count = ( ( cdc_union->header.len -
 | 
		
	
		
			
			|  | 1030 | +		desc->count = ( ( cdc_union->header.len -
 | 
		
	
		
			
			| 960 | 1031 |  				  offsetof ( typeof ( *cdc_union ),
 | 
		
	
		
			
			| 961 | 1032 |  					     interface[0] ) ) /
 | 
		
	
		
			
			| 962 | 1033 |  				sizeof ( cdc_union->interface[0] ) );
 | 
		
	
		
			
			| 963 |  | -		if ( func->count > config->interfaces ) {
 | 
		
	
		
			
			|  | 1034 | +		if ( desc->count > config->interfaces ) {
 | 
		
	
		
			
			| 964 | 1035 |  			DBGC ( usb, "USB %s has invalid union functional "
 | 
		
	
		
			
			| 965 | 1036 |  			       "descriptor with %d interfaces\n",
 | 
		
	
		
			
			| 966 |  | -			       func->name, func->count );
 | 
		
	
		
			
			|  | 1037 | +			       usb->name, desc->count );
 | 
		
	
		
			
			| 967 | 1038 |  			return -ERANGE;
 | 
		
	
		
			
			| 968 | 1039 |  		}
 | 
		
	
		
			
			| 969 | 1040 |  
 | 
		
	
		
			
			| 970 | 1041 |  		/* Describe function */
 | 
		
	
		
			
			| 971 |  | -		for ( i = 0 ; i < func->count ; i++ )
 | 
		
	
		
			
			| 972 |  | -			func->interface[i] = cdc_union->interface[i];
 | 
		
	
		
			
			|  | 1042 | +		for ( i = 0 ; i < desc->count ; i++ ) {
 | 
		
	
		
			
			|  | 1043 | +			if ( cdc_union->interface[i] >= config->interfaces ) {
 | 
		
	
		
			
			|  | 1044 | +				DBGC ( usb, "USB %s has invalid union "
 | 
		
	
		
			
			|  | 1045 | +				       "functional descriptor covering "
 | 
		
	
		
			
			|  | 1046 | +				       "interface %d\n", usb->name,
 | 
		
	
		
			
			|  | 1047 | +				       cdc_union->interface[i] );
 | 
		
	
		
			
			|  | 1048 | +				return -ERANGE;
 | 
		
	
		
			
			|  | 1049 | +			}
 | 
		
	
		
			
			|  | 1050 | +			interfaces[i] = cdc_union->interface[i];
 | 
		
	
		
			
			|  | 1051 | +		}
 | 
		
	
		
			
			| 973 | 1052 |  
 | 
		
	
		
			
			| 974 | 1053 |  		return 0;
 | 
		
	
		
			
			| 975 | 1054 |  	}
 | 
		
	
	
		
			
			|  | @@ -977,17 +1056,38 @@ static int usb_function ( struct usb_function *func,
 | 
		
	
		
			
			| 977 | 1056 |  	return 0;
 | 
		
	
		
			
			| 978 | 1057 |  }
 | 
		
	
		
			
			| 979 | 1058 |  
 | 
		
	
		
			
			|  | 1059 | +/**
 | 
		
	
		
			
			|  | 1060 | + * Update list of used interface
 | 
		
	
		
			
			|  | 1061 | + *
 | 
		
	
		
			
			|  | 1062 | + * @v usb		USB device
 | 
		
	
		
			
			|  | 1063 | + * @v count		Number of interfaces
 | 
		
	
		
			
			|  | 1064 | + * @v interface		List of interfaces
 | 
		
	
		
			
			|  | 1065 | + * @v used		List of already-used interfaces
 | 
		
	
		
			
			|  | 1066 | + * @ret rc		Return status code
 | 
		
	
		
			
			|  | 1067 | + */
 | 
		
	
		
			
			|  | 1068 | +static int usb_used ( struct usb_device *usb, unsigned int count,
 | 
		
	
		
			
			|  | 1069 | +		      uint8_t *interface, uint8_t *used ) {
 | 
		
	
		
			
			|  | 1070 | +	unsigned int i;
 | 
		
	
		
			
			|  | 1071 | +
 | 
		
	
		
			
			|  | 1072 | +	for ( i = 0 ; i < count ; i++ ) {
 | 
		
	
		
			
			|  | 1073 | +		if ( used[interface[i]] ) {
 | 
		
	
		
			
			|  | 1074 | +			DBGC ( usb, "USB %s interface %d already in use\n",
 | 
		
	
		
			
			|  | 1075 | +			       usb->name, interface[i] );
 | 
		
	
		
			
			|  | 1076 | +			return -EINVAL;
 | 
		
	
		
			
			|  | 1077 | +		}
 | 
		
	
		
			
			|  | 1078 | +		used[interface[i]] = 1;
 | 
		
	
		
			
			|  | 1079 | +	}
 | 
		
	
		
			
			|  | 1080 | +	return 0;
 | 
		
	
		
			
			|  | 1081 | +}
 | 
		
	
		
			
			|  | 1082 | +
 | 
		
	
		
			
			| 980 | 1083 |  /**
 | 
		
	
		
			
			| 981 | 1084 |   * Find USB device driver
 | 
		
	
		
			
			| 982 | 1085 |   *
 | 
		
	
		
			
			| 983 |  | - * @v vendor		Vendor ID
 | 
		
	
		
			
			| 984 |  | - * @v product		Product ID
 | 
		
	
		
			
			| 985 |  | - * @v class		Class
 | 
		
	
		
			
			|  | 1086 | + * @v desc		Function descriptor
 | 
		
	
		
			
			| 986 | 1087 |   * @ret id		USB device ID, or NULL
 | 
		
	
		
			
			| 987 | 1088 |   * @ret driver		USB device driver, or NULL
 | 
		
	
		
			
			| 988 | 1089 |   */
 | 
		
	
		
			
			| 989 |  | -struct usb_driver * usb_find_driver ( unsigned int vendor, unsigned int product,
 | 
		
	
		
			
			| 990 |  | -				      struct usb_class *class,
 | 
		
	
		
			
			|  | 1090 | +struct usb_driver * usb_find_driver ( struct usb_function_descriptor *desc,
 | 
		
	
		
			
			| 991 | 1091 |  				      struct usb_device_id **id ) {
 | 
		
	
		
			
			| 992 | 1092 |  	struct usb_driver *driver;
 | 
		
	
		
			
			| 993 | 1093 |  	unsigned int i;
 | 
		
	
	
		
			
			|  | @@ -998,13 +1098,13 @@ struct usb_driver * usb_find_driver ( unsigned int vendor, unsigned int product,
 | 
		
	
		
			
			| 998 | 1098 |  
 | 
		
	
		
			
			| 999 | 1099 |  			/* Check for a matching ID */
 | 
		
	
		
			
			| 1000 | 1100 |  			*id = &driver->ids[i];
 | 
		
	
		
			
			| 1001 |  | -			if ( ( ( (*id)->vendor == vendor ) ||
 | 
		
	
		
			
			|  | 1101 | +			if ( ( ( (*id)->vendor == desc->vendor ) ||
 | 
		
	
		
			
			| 1002 | 1102 |  			       ( (*id)->vendor == USB_ANY_ID ) ) &&
 | 
		
	
		
			
			| 1003 |  | -			     ( ( (*id)->product == product ) ||
 | 
		
	
		
			
			|  | 1103 | +			     ( ( (*id)->product == desc->product ) ||
 | 
		
	
		
			
			| 1004 | 1104 |  			       ( (*id)->product == USB_ANY_ID ) ) &&
 | 
		
	
		
			
			| 1005 |  | -			     ( (*id)->class.class == class->class ) &&
 | 
		
	
		
			
			| 1006 |  | -			     ( (*id)->class.subclass == class->subclass ) &&
 | 
		
	
		
			
			| 1007 |  | -			     ( (*id)->class.protocol == class->protocol ) )
 | 
		
	
		
			
			|  | 1105 | +			     ( (*id)->class.class == desc->class.class ) &&
 | 
		
	
		
			
			|  | 1106 | +			     ( (*id)->class.subclass == desc->class.subclass )&&
 | 
		
	
		
			
			|  | 1107 | +			     ( (*id)->class.protocol == desc->class.protocol ) )
 | 
		
	
		
			
			| 1008 | 1108 |  				return driver;
 | 
		
	
		
			
			| 1009 | 1109 |  		}
 | 
		
	
		
			
			| 1010 | 1110 |  	}
 | 
		
	
	
		
			
			|  | @@ -1014,6 +1114,51 @@ struct usb_driver * usb_find_driver ( unsigned int vendor, unsigned int product,
 | 
		
	
		
			
			| 1014 | 1114 |  	return NULL;
 | 
		
	
		
			
			| 1015 | 1115 |  }
 | 
		
	
		
			
			| 1016 | 1116 |  
 | 
		
	
		
			
			|  | 1117 | +/**
 | 
		
	
		
			
			|  | 1118 | + * Get USB device configuration score
 | 
		
	
		
			
			|  | 1119 | + *
 | 
		
	
		
			
			|  | 1120 | + * @v usb		USB device
 | 
		
	
		
			
			|  | 1121 | + * @v config		Configuration descriptor
 | 
		
	
		
			
			|  | 1122 | + * @ret score		Device configuration score, or negative error
 | 
		
	
		
			
			|  | 1123 | + */
 | 
		
	
		
			
			|  | 1124 | +static int usb_score ( struct usb_device *usb,
 | 
		
	
		
			
			|  | 1125 | +		       struct usb_configuration_descriptor *config ) {
 | 
		
	
		
			
			|  | 1126 | +	uint8_t used[config->interfaces];
 | 
		
	
		
			
			|  | 1127 | +	uint8_t interface[config->interfaces];
 | 
		
	
		
			
			|  | 1128 | +	struct usb_function_descriptor desc;
 | 
		
	
		
			
			|  | 1129 | +	struct usb_driver *driver;
 | 
		
	
		
			
			|  | 1130 | +	struct usb_device_id *id;
 | 
		
	
		
			
			|  | 1131 | +	unsigned int first;
 | 
		
	
		
			
			|  | 1132 | +	unsigned int score = 0;
 | 
		
	
		
			
			|  | 1133 | +	int rc;
 | 
		
	
		
			
			|  | 1134 | +
 | 
		
	
		
			
			|  | 1135 | +	/* Identify each function in turn */
 | 
		
	
		
			
			|  | 1136 | +	memset ( used, 0, sizeof ( used ) );
 | 
		
	
		
			
			|  | 1137 | +	for ( first = 0 ; first < config->interfaces ; first++ ) {
 | 
		
	
		
			
			|  | 1138 | +
 | 
		
	
		
			
			|  | 1139 | +		/* Skip interfaces already used */
 | 
		
	
		
			
			|  | 1140 | +		if ( used[first] )
 | 
		
	
		
			
			|  | 1141 | +			continue;
 | 
		
	
		
			
			|  | 1142 | +
 | 
		
	
		
			
			|  | 1143 | +		/* Describe function */
 | 
		
	
		
			
			|  | 1144 | +		if ( ( rc = usb_describe ( usb, config, first, interface,
 | 
		
	
		
			
			|  | 1145 | +					   &desc ) ) != 0 )
 | 
		
	
		
			
			|  | 1146 | +			return rc;
 | 
		
	
		
			
			|  | 1147 | +
 | 
		
	
		
			
			|  | 1148 | +		/* Update used interfaces */
 | 
		
	
		
			
			|  | 1149 | +		if ( ( rc = usb_used ( usb, desc.count, interface,
 | 
		
	
		
			
			|  | 1150 | +				       used ) ) != 0 )
 | 
		
	
		
			
			|  | 1151 | +			return rc;
 | 
		
	
		
			
			|  | 1152 | +
 | 
		
	
		
			
			|  | 1153 | +		/* Look for a driver for this function */
 | 
		
	
		
			
			|  | 1154 | +		driver = usb_find_driver ( &desc, &id );
 | 
		
	
		
			
			|  | 1155 | +		if ( driver )
 | 
		
	
		
			
			|  | 1156 | +			score += driver->score;
 | 
		
	
		
			
			|  | 1157 | +	}
 | 
		
	
		
			
			|  | 1158 | +
 | 
		
	
		
			
			|  | 1159 | +	return score;
 | 
		
	
		
			
			|  | 1160 | +}
 | 
		
	
		
			
			|  | 1161 | +
 | 
		
	
		
			
			| 1017 | 1162 |  /**
 | 
		
	
		
			
			| 1018 | 1163 |   * Probe USB device driver
 | 
		
	
		
			
			| 1019 | 1164 |   *
 | 
		
	
	
		
			
			|  | @@ -1029,13 +1174,12 @@ static int usb_probe ( struct usb_function *func,
 | 
		
	
		
			
			| 1029 | 1174 |  	int rc;
 | 
		
	
		
			
			| 1030 | 1175 |  
 | 
		
	
		
			
			| 1031 | 1176 |  	/* Identify driver */
 | 
		
	
		
			
			| 1032 |  | -	driver = usb_find_driver ( func->dev.desc.vendor, func->dev.desc.device,
 | 
		
	
		
			
			| 1033 |  | -				   &func->class, &id );
 | 
		
	
		
			
			|  | 1177 | +	driver = usb_find_driver ( &func->desc, &id );
 | 
		
	
		
			
			| 1034 | 1178 |  	if ( ! driver ) {
 | 
		
	
		
			
			| 1035 | 1179 |  		DBGC ( usb, "USB %s %04x:%04x class %d:%d:%d has no driver\n",
 | 
		
	
		
			
			| 1036 |  | -		       func->name, func->dev.desc.vendor, func->dev.desc.device,
 | 
		
	
		
			
			| 1037 |  | -		       func->class.class, func->class.subclass,
 | 
		
	
		
			
			| 1038 |  | -		       func->class.protocol );
 | 
		
	
		
			
			|  | 1180 | +		       func->name, func->desc.vendor, func->desc.product,
 | 
		
	
		
			
			|  | 1181 | +		       func->desc.class.class, func->desc.class.subclass,
 | 
		
	
		
			
			|  | 1182 | +		       func->desc.class.protocol );
 | 
		
	
		
			
			| 1039 | 1183 |  		return -ENOENT;
 | 
		
	
		
			
			| 1040 | 1184 |  	}
 | 
		
	
		
			
			| 1041 | 1185 |  
 | 
		
	
	
		
			
			|  | @@ -1106,28 +1250,24 @@ usb_probe_all ( struct usb_device *usb,
 | 
		
	
		
			
			| 1106 | 1250 |  		list_add_tail ( &func->list, &usb->functions );
 | 
		
	
		
			
			| 1107 | 1251 |  
 | 
		
	
		
			
			| 1108 | 1252 |  		/* Identify function */
 | 
		
	
		
			
			| 1109 |  | -		if ( ( rc = usb_function ( func, config, first ) ) != 0 )
 | 
		
	
		
			
			| 1110 |  | -			goto err_function;
 | 
		
	
		
			
			| 1111 |  | -		assert ( func->count <= config->interfaces );
 | 
		
	
		
			
			|  | 1253 | +		if ( ( rc = usb_describe ( usb, config, first, func->interface,
 | 
		
	
		
			
			|  | 1254 | +					   &func->desc ) ) != 0 )
 | 
		
	
		
			
			|  | 1255 | +			goto err_describe;
 | 
		
	
		
			
			|  | 1256 | +		assert ( func->desc.count <= config->interfaces );
 | 
		
	
		
			
			| 1112 | 1257 |  
 | 
		
	
		
			
			| 1113 | 1258 |  		/* Mark interfaces as used */
 | 
		
	
		
			
			| 1114 |  | -		for ( i = 0 ; i < func->count ; i++ ) {
 | 
		
	
		
			
			| 1115 |  | -			if ( func->interface[i] >= config->interfaces ) {
 | 
		
	
		
			
			| 1116 |  | -				DBGC ( usb, "USB %s has invalid interface %d\n",
 | 
		
	
		
			
			| 1117 |  | -				       func->name, func->interface[i] );
 | 
		
	
		
			
			| 1118 |  | -				goto err_interface;
 | 
		
	
		
			
			| 1119 |  | -			}
 | 
		
	
		
			
			| 1120 |  | -			used[ func->interface[i] ] = 1;
 | 
		
	
		
			
			| 1121 |  | -		}
 | 
		
	
		
			
			|  | 1259 | +		if ( ( rc = usb_used ( usb, func->desc.count, func->interface,
 | 
		
	
		
			
			|  | 1260 | +				       used ) ) != 0 )
 | 
		
	
		
			
			|  | 1261 | +			goto err_used;
 | 
		
	
		
			
			| 1122 | 1262 |  
 | 
		
	
		
			
			| 1123 | 1263 |  		/* Probe device driver */
 | 
		
	
		
			
			| 1124 | 1264 |  		if ( ( rc = usb_probe ( func, config ) ) != 0 )
 | 
		
	
		
			
			| 1125 | 1265 |  			goto err_probe;
 | 
		
	
		
			
			| 1126 | 1266 |  		DBGC ( usb, "USB %s %04x:%04x class %d:%d:%d interfaces ",
 | 
		
	
		
			
			| 1127 |  | -		       func->name, func->dev.desc.vendor, func->dev.desc.device,
 | 
		
	
		
			
			| 1128 |  | -		       func->class.class, func->class.subclass,
 | 
		
	
		
			
			| 1129 |  | -		       func->class.protocol );
 | 
		
	
		
			
			| 1130 |  | -		for ( i = 0 ; i < func->count ; i++ )
 | 
		
	
		
			
			|  | 1267 | +		       func->name, func->desc.vendor, func->desc.product,
 | 
		
	
		
			
			|  | 1268 | +		       func->desc.class.class, func->desc.class.subclass,
 | 
		
	
		
			
			|  | 1269 | +		       func->desc.class.protocol );
 | 
		
	
		
			
			|  | 1270 | +		for ( i = 0 ; i < func->desc.count ; i++ )
 | 
		
	
		
			
			| 1131 | 1271 |  			DBGC ( usb, "%s%d", ( i ? "," : "" ),
 | 
		
	
		
			
			| 1132 | 1272 |  			       func->interface[i] );
 | 
		
	
		
			
			| 1133 | 1273 |  		DBGC ( usb, " using driver %s\n", func->dev.driver_name );
 | 
		
	
	
		
			
			|  | @@ -1140,8 +1280,8 @@ usb_probe_all ( struct usb_device *usb,
 | 
		
	
		
			
			| 1140 | 1280 |  		list_del ( &func->dev.siblings );
 | 
		
	
		
			
			| 1141 | 1281 |  		usb_remove ( func );
 | 
		
	
		
			
			| 1142 | 1282 |  	err_probe:
 | 
		
	
		
			
			| 1143 |  | -	err_interface:
 | 
		
	
		
			
			| 1144 |  | -	err_function:
 | 
		
	
		
			
			|  | 1283 | +	err_used:
 | 
		
	
		
			
			|  | 1284 | +	err_describe:
 | 
		
	
		
			
			| 1145 | 1285 |  		list_del ( &func->list );
 | 
		
	
		
			
			| 1146 | 1286 |  		free ( func );
 | 
		
	
		
			
			| 1147 | 1287 |  	err_alloc:
 | 
		
	
	
		
			
			|  | @@ -1177,82 +1317,6 @@ static void usb_remove_all ( struct usb_device *usb ) {
 | 
		
	
		
			
			| 1177 | 1317 |  	}
 | 
		
	
		
			
			| 1178 | 1318 |  }
 | 
		
	
		
			
			| 1179 | 1319 |  
 | 
		
	
		
			
			| 1180 |  | -/**
 | 
		
	
		
			
			| 1181 |  | - * Select USB device configuration
 | 
		
	
		
			
			| 1182 |  | - *
 | 
		
	
		
			
			| 1183 |  | - * @v usb		USB device
 | 
		
	
		
			
			| 1184 |  | - * @v index		Configuration index
 | 
		
	
		
			
			| 1185 |  | - * @ret rc		Return status code
 | 
		
	
		
			
			| 1186 |  | - */
 | 
		
	
		
			
			| 1187 |  | -static int usb_configure ( struct usb_device *usb, unsigned int index ) {
 | 
		
	
		
			
			| 1188 |  | -	struct usb_configuration_descriptor partial;
 | 
		
	
		
			
			| 1189 |  | -	struct usb_configuration_descriptor *config;
 | 
		
	
		
			
			| 1190 |  | -	size_t len;
 | 
		
	
		
			
			| 1191 |  | -	int rc;
 | 
		
	
		
			
			| 1192 |  | -
 | 
		
	
		
			
			| 1193 |  | -	/* Read first part of configuration descriptor to get size */
 | 
		
	
		
			
			| 1194 |  | -	if ( ( rc = usb_get_config_descriptor ( usb, index, &partial,
 | 
		
	
		
			
			| 1195 |  | -						sizeof ( partial ) ) ) != 0 ) {
 | 
		
	
		
			
			| 1196 |  | -		DBGC ( usb, "USB %s could not get configuration descriptor %d: "
 | 
		
	
		
			
			| 1197 |  | -		       "%s\n", usb->name, index, strerror ( rc ) );
 | 
		
	
		
			
			| 1198 |  | -		goto err_get_partial;
 | 
		
	
		
			
			| 1199 |  | -	}
 | 
		
	
		
			
			| 1200 |  | -	len = le16_to_cpu ( partial.len );
 | 
		
	
		
			
			| 1201 |  | -	if ( len < sizeof ( partial ) ) {
 | 
		
	
		
			
			| 1202 |  | -		DBGC ( usb, "USB %s underlength configuraton descriptor %d\n",
 | 
		
	
		
			
			| 1203 |  | -		       usb->name, index );
 | 
		
	
		
			
			| 1204 |  | -		rc = -EINVAL;
 | 
		
	
		
			
			| 1205 |  | -		goto err_partial_len;
 | 
		
	
		
			
			| 1206 |  | -	}
 | 
		
	
		
			
			| 1207 |  | -
 | 
		
	
		
			
			| 1208 |  | -	/* Allocate buffer for whole configuration descriptor */
 | 
		
	
		
			
			| 1209 |  | -	config = malloc ( len );
 | 
		
	
		
			
			| 1210 |  | -	if ( ! config ) {
 | 
		
	
		
			
			| 1211 |  | -		rc = -ENOMEM;
 | 
		
	
		
			
			| 1212 |  | -		goto err_alloc_config;
 | 
		
	
		
			
			| 1213 |  | -	}
 | 
		
	
		
			
			| 1214 |  | -
 | 
		
	
		
			
			| 1215 |  | -	/* Read whole configuration descriptor */
 | 
		
	
		
			
			| 1216 |  | -	if ( ( rc = usb_get_config_descriptor ( usb, index, config,
 | 
		
	
		
			
			| 1217 |  | -						len ) ) != 0 ) {
 | 
		
	
		
			
			| 1218 |  | -		DBGC ( usb, "USB %s could not get configuration descriptor %d: "
 | 
		
	
		
			
			| 1219 |  | -		       "%s\n", usb->name, index, strerror ( rc ) );
 | 
		
	
		
			
			| 1220 |  | -		goto err_get_config_descriptor;
 | 
		
	
		
			
			| 1221 |  | -	}
 | 
		
	
		
			
			| 1222 |  | -	if ( config->len != partial.len ) {
 | 
		
	
		
			
			| 1223 |  | -		DBGC ( usb, "USB %s bad configuration descriptor %d length\n",
 | 
		
	
		
			
			| 1224 |  | -		       usb->name, index );
 | 
		
	
		
			
			| 1225 |  | -		rc = -EINVAL;
 | 
		
	
		
			
			| 1226 |  | -		goto err_config_len;
 | 
		
	
		
			
			| 1227 |  | -	}
 | 
		
	
		
			
			| 1228 |  | -
 | 
		
	
		
			
			| 1229 |  | -	/* Set configuration */
 | 
		
	
		
			
			| 1230 |  | -	if ( ( rc = usb_set_configuration ( usb, config->config ) ) != 0){
 | 
		
	
		
			
			| 1231 |  | -		DBGC ( usb, "USB %s could not set configuration %d: %s\n",
 | 
		
	
		
			
			| 1232 |  | -		       usb->name, config->config, strerror ( rc ) );
 | 
		
	
		
			
			| 1233 |  | -		goto err_set_configuration;
 | 
		
	
		
			
			| 1234 |  | -	}
 | 
		
	
		
			
			| 1235 |  | -
 | 
		
	
		
			
			| 1236 |  | -	/* Probe USB device drivers */
 | 
		
	
		
			
			| 1237 |  | -	usb_probe_all ( usb, config );
 | 
		
	
		
			
			| 1238 |  | -
 | 
		
	
		
			
			| 1239 |  | -	/* Free configuration descriptor */
 | 
		
	
		
			
			| 1240 |  | -	free ( config );
 | 
		
	
		
			
			| 1241 |  | -
 | 
		
	
		
			
			| 1242 |  | -	return 0;
 | 
		
	
		
			
			| 1243 |  | -
 | 
		
	
		
			
			| 1244 |  | -	usb_remove_all ( usb );
 | 
		
	
		
			
			| 1245 |  | -	usb_set_configuration ( usb, 0 );
 | 
		
	
		
			
			| 1246 |  | - err_set_configuration:
 | 
		
	
		
			
			| 1247 |  | - err_config_len:
 | 
		
	
		
			
			| 1248 |  | - err_get_config_descriptor:
 | 
		
	
		
			
			| 1249 |  | -	free ( config );
 | 
		
	
		
			
			| 1250 |  | - err_alloc_config:
 | 
		
	
		
			
			| 1251 |  | - err_partial_len:
 | 
		
	
		
			
			| 1252 |  | - err_get_partial:
 | 
		
	
		
			
			| 1253 |  | -	return rc;
 | 
		
	
		
			
			| 1254 |  | -}
 | 
		
	
		
			
			| 1255 |  | -
 | 
		
	
		
			
			| 1256 | 1320 |  /**
 | 
		
	
		
			
			| 1257 | 1321 |   * Clear USB device configuration
 | 
		
	
		
			
			| 1258 | 1322 |   *
 | 
		
	
	
		
			
			|  | @@ -1275,32 +1339,76 @@ static void usb_deconfigure ( struct usb_device *usb ) {
 | 
		
	
		
			
			| 1275 | 1339 |  }
 | 
		
	
		
			
			| 1276 | 1340 |  
 | 
		
	
		
			
			| 1277 | 1341 |  /**
 | 
		
	
		
			
			| 1278 |  | - * Find and select a supported USB device configuration
 | 
		
	
		
			
			|  | 1342 | + * Choose our preferred USB device configuration
 | 
		
	
		
			
			| 1279 | 1343 |   *
 | 
		
	
		
			
			| 1280 | 1344 |   * @v usb		USB device
 | 
		
	
		
			
			| 1281 | 1345 |   * @ret rc		Return status code
 | 
		
	
		
			
			| 1282 | 1346 |   */
 | 
		
	
		
			
			| 1283 |  | -static int usb_configure_any ( struct usb_device *usb ) {
 | 
		
	
		
			
			|  | 1347 | +static int usb_autoconfigure ( struct usb_device *usb ) {
 | 
		
	
		
			
			|  | 1348 | +	struct usb_configuration_descriptor *config;
 | 
		
	
		
			
			|  | 1349 | +	unsigned int preferred = 0;
 | 
		
	
		
			
			| 1284 | 1350 |  	unsigned int index;
 | 
		
	
		
			
			| 1285 |  | -	int rc = -ENOENT;
 | 
		
	
		
			
			|  | 1351 | +	int score;
 | 
		
	
		
			
			|  | 1352 | +	int best = 0;
 | 
		
	
		
			
			|  | 1353 | +	int rc;
 | 
		
	
		
			
			| 1286 | 1354 |  
 | 
		
	
		
			
			| 1287 |  | -	/* Attempt all configuration indexes */
 | 
		
	
		
			
			|  | 1355 | +	/* Calculate driver score for each configuration index */
 | 
		
	
		
			
			| 1288 | 1356 |  	for ( index = 0 ; index < usb->device.configurations ; index++ ) {
 | 
		
	
		
			
			| 1289 | 1357 |  
 | 
		
	
		
			
			| 1290 |  | -		/* Attempt this configuration index */
 | 
		
	
		
			
			| 1291 |  | -		if ( ( rc = usb_configure ( usb, index ) ) != 0 )
 | 
		
	
		
			
			| 1292 |  | -			continue;
 | 
		
	
		
			
			|  | 1358 | +		/* Read configuration descriptor */
 | 
		
	
		
			
			|  | 1359 | +		if ( ( rc = usb_config_descriptor ( usb, index,
 | 
		
	
		
			
			|  | 1360 | +						    &config ) ) != 0 )
 | 
		
	
		
			
			|  | 1361 | +			goto err_config;
 | 
		
	
		
			
			| 1293 | 1362 |  
 | 
		
	
		
			
			| 1294 |  | -		/* If we have no drivers, then try the next configuration */
 | 
		
	
		
			
			| 1295 |  | -		if ( list_empty ( &usb->functions ) ) {
 | 
		
	
		
			
			| 1296 |  | -			rc = -ENOTSUP;
 | 
		
	
		
			
			| 1297 |  | -			usb_deconfigure ( usb );
 | 
		
	
		
			
			| 1298 |  | -			continue;
 | 
		
	
		
			
			|  | 1363 | +		/* Get score for this configuration */
 | 
		
	
		
			
			|  | 1364 | +		score = usb_score ( usb, config );
 | 
		
	
		
			
			|  | 1365 | +		if ( score < 0 ) {
 | 
		
	
		
			
			|  | 1366 | +			rc = score;
 | 
		
	
		
			
			|  | 1367 | +			goto err_score;
 | 
		
	
		
			
			| 1299 | 1368 |  		}
 | 
		
	
		
			
			|  | 1369 | +		DBGC2 ( usb, "USB %s configuration %d score %d\n",
 | 
		
	
		
			
			|  | 1370 | +			usb->name, config->config, score );
 | 
		
	
		
			
			| 1300 | 1371 |  
 | 
		
	
		
			
			| 1301 |  | -		return 0;
 | 
		
	
		
			
			|  | 1372 | +		/* Record as preferred configuration, if applicable */
 | 
		
	
		
			
			|  | 1373 | +		if ( score > best ) {
 | 
		
	
		
			
			|  | 1374 | +			best = score;
 | 
		
	
		
			
			|  | 1375 | +			preferred = index;
 | 
		
	
		
			
			|  | 1376 | +		}
 | 
		
	
		
			
			|  | 1377 | +
 | 
		
	
		
			
			|  | 1378 | +		/* Free configuration descriptor */
 | 
		
	
		
			
			|  | 1379 | +		free ( config );
 | 
		
	
		
			
			|  | 1380 | +		config = NULL;
 | 
		
	
		
			
			| 1302 | 1381 |  	}
 | 
		
	
		
			
			| 1303 | 1382 |  
 | 
		
	
		
			
			|  | 1383 | +	/* Read preferred configuration descriptor */
 | 
		
	
		
			
			|  | 1384 | +	if ( ( rc = usb_config_descriptor ( usb, preferred, &config ) ) != 0 )
 | 
		
	
		
			
			|  | 1385 | +		goto err_preferred;
 | 
		
	
		
			
			|  | 1386 | +
 | 
		
	
		
			
			|  | 1387 | +	/* Set configuration */
 | 
		
	
		
			
			|  | 1388 | +	if ( ( rc = usb_set_configuration ( usb, config->config ) ) != 0){
 | 
		
	
		
			
			|  | 1389 | +		DBGC ( usb, "USB %s could not set configuration %d: %s\n",
 | 
		
	
		
			
			|  | 1390 | +		       usb->name, config->config, strerror ( rc ) );
 | 
		
	
		
			
			|  | 1391 | +		goto err_set_configuration;
 | 
		
	
		
			
			|  | 1392 | +	}
 | 
		
	
		
			
			|  | 1393 | +
 | 
		
	
		
			
			|  | 1394 | +	/* Probe USB device drivers */
 | 
		
	
		
			
			|  | 1395 | +	usb_probe_all ( usb, config );
 | 
		
	
		
			
			|  | 1396 | +
 | 
		
	
		
			
			|  | 1397 | +	/* Free configuration descriptor */
 | 
		
	
		
			
			|  | 1398 | +	free ( config );
 | 
		
	
		
			
			|  | 1399 | +
 | 
		
	
		
			
			|  | 1400 | +	return 0;
 | 
		
	
		
			
			|  | 1401 | +
 | 
		
	
		
			
			|  | 1402 | +	usb_remove_all ( usb );
 | 
		
	
		
			
			|  | 1403 | +	usb_set_configuration ( usb, 0 );
 | 
		
	
		
			
			|  | 1404 | + err_set_configuration:
 | 
		
	
		
			
			|  | 1405 | +	free ( config );
 | 
		
	
		
			
			|  | 1406 | + err_preferred:
 | 
		
	
		
			
			|  | 1407 | +	return rc;
 | 
		
	
		
			
			|  | 1408 | +
 | 
		
	
		
			
			|  | 1409 | + err_score:
 | 
		
	
		
			
			|  | 1410 | +	free ( config );
 | 
		
	
		
			
			|  | 1411 | + err_config:
 | 
		
	
		
			
			| 1304 | 1412 |  	return rc;
 | 
		
	
		
			
			| 1305 | 1413 |  }
 | 
		
	
		
			
			| 1306 | 1414 |  
 | 
		
	
	
		
			
			|  | @@ -1444,13 +1552,13 @@ static int register_usb ( struct usb_device *usb ) {
 | 
		
	
		
			
			| 1444 | 1552 |  	       usb_speed_name ( port->speed ), usb->control.mtu );
 | 
		
	
		
			
			| 1445 | 1553 |  
 | 
		
	
		
			
			| 1446 | 1554 |  	/* Configure device */
 | 
		
	
		
			
			| 1447 |  | -	if ( ( rc = usb_configure_any ( usb ) ) != 0 )
 | 
		
	
		
			
			| 1448 |  | -		goto err_configure_any;
 | 
		
	
		
			
			|  | 1555 | +	if ( ( rc = usb_autoconfigure ( usb ) ) != 0 )
 | 
		
	
		
			
			|  | 1556 | +		goto err_autoconfigure;
 | 
		
	
		
			
			| 1449 | 1557 |  
 | 
		
	
		
			
			| 1450 | 1558 |  	return 0;
 | 
		
	
		
			
			| 1451 | 1559 |  
 | 
		
	
		
			
			| 1452 | 1560 |  	usb_deconfigure ( usb );
 | 
		
	
		
			
			| 1453 |  | - err_configure_any:
 | 
		
	
		
			
			|  | 1561 | + err_autoconfigure:
 | 
		
	
		
			
			| 1454 | 1562 |   err_get_device_descriptor:
 | 
		
	
		
			
			| 1455 | 1563 |   err_mtu:
 | 
		
	
		
			
			| 1456 | 1564 |   err_get_mtu:
 |