|  | @@ -90,12 +90,12 @@ static int vmbus_post_empty_message ( struct hv_hypervisor *hv,
 | 
		
	
		
			
			| 90 | 90 |  }
 | 
		
	
		
			
			| 91 | 91 |  
 | 
		
	
		
			
			| 92 | 92 |  /**
 | 
		
	
		
			
			| 93 |  | - * Wait for received message
 | 
		
	
		
			
			|  | 93 | + * Wait for received message of any type
 | 
		
	
		
			
			| 94 | 94 |   *
 | 
		
	
		
			
			| 95 | 95 |   * @v hv		Hyper-V hypervisor
 | 
		
	
		
			
			| 96 | 96 |   * @ret rc		Return status code
 | 
		
	
		
			
			| 97 | 97 |   */
 | 
		
	
		
			
			| 98 |  | -static int vmbus_wait_for_message ( struct hv_hypervisor *hv ) {
 | 
		
	
		
			
			|  | 98 | +static int vmbus_wait_for_any_message ( struct hv_hypervisor *hv ) {
 | 
		
	
		
			
			| 99 | 99 |  	struct vmbus *vmbus = hv->vmbus;
 | 
		
	
		
			
			| 100 | 100 |  	int rc;
 | 
		
	
		
			
			| 101 | 101 |  
 | 
		
	
	
		
			
			|  | @@ -116,6 +116,38 @@ static int vmbus_wait_for_message ( struct hv_hypervisor *hv ) {
 | 
		
	
		
			
			| 116 | 116 |  	return 0;
 | 
		
	
		
			
			| 117 | 117 |  }
 | 
		
	
		
			
			| 118 | 118 |  
 | 
		
	
		
			
			|  | 119 | +/**
 | 
		
	
		
			
			|  | 120 | + * Wait for received message of a specified type, ignoring any others
 | 
		
	
		
			
			|  | 121 | + *
 | 
		
	
		
			
			|  | 122 | + * @v hv		Hyper-V hypervisor
 | 
		
	
		
			
			|  | 123 | + * @v type		Message type
 | 
		
	
		
			
			|  | 124 | + * @ret rc		Return status code
 | 
		
	
		
			
			|  | 125 | + */
 | 
		
	
		
			
			|  | 126 | +static int vmbus_wait_for_message ( struct hv_hypervisor *hv,
 | 
		
	
		
			
			|  | 127 | +				    unsigned int type ) {
 | 
		
	
		
			
			|  | 128 | +	struct vmbus *vmbus = hv->vmbus;
 | 
		
	
		
			
			|  | 129 | +	const struct vmbus_message_header *header = &vmbus->message->header;
 | 
		
	
		
			
			|  | 130 | +	int rc;
 | 
		
	
		
			
			|  | 131 | +
 | 
		
	
		
			
			|  | 132 | +	/* Loop until specified message arrives, or until an error occurs */
 | 
		
	
		
			
			|  | 133 | +	while ( 1 ) {
 | 
		
	
		
			
			|  | 134 | +
 | 
		
	
		
			
			|  | 135 | +		/* Wait for message */
 | 
		
	
		
			
			|  | 136 | +		if ( ( rc = vmbus_wait_for_any_message ( hv ) ) != 0 )
 | 
		
	
		
			
			|  | 137 | +			return rc;
 | 
		
	
		
			
			|  | 138 | +
 | 
		
	
		
			
			|  | 139 | +		/* Check for requested message type */
 | 
		
	
		
			
			|  | 140 | +		if ( header->type == cpu_to_le32 ( type ) )
 | 
		
	
		
			
			|  | 141 | +			return 0;
 | 
		
	
		
			
			|  | 142 | +
 | 
		
	
		
			
			|  | 143 | +		/* Ignore any other messages (e.g. due to additional
 | 
		
	
		
			
			|  | 144 | +		 * channels being offered at runtime).
 | 
		
	
		
			
			|  | 145 | +		 */
 | 
		
	
		
			
			|  | 146 | +		DBGC ( vmbus, "VMBUS %p ignoring message type %d (expecting "
 | 
		
	
		
			
			|  | 147 | +		       "%d)\n", vmbus, le32_to_cpu ( header->type ), type );
 | 
		
	
		
			
			|  | 148 | +	}
 | 
		
	
		
			
			|  | 149 | +}
 | 
		
	
		
			
			|  | 150 | +
 | 
		
	
		
			
			| 119 | 151 |  /**
 | 
		
	
		
			
			| 120 | 152 |   * Initiate contact
 | 
		
	
		
			
			| 121 | 153 |   *
 | 
		
	
	
		
			
			|  | @@ -144,15 +176,10 @@ static int vmbus_initiate_contact ( struct hv_hypervisor *hv,
 | 
		
	
		
			
			| 144 | 176 |  		return rc;
 | 
		
	
		
			
			| 145 | 177 |  
 | 
		
	
		
			
			| 146 | 178 |  	/* Wait for response */
 | 
		
	
		
			
			| 147 |  | -	if ( ( rc = vmbus_wait_for_message ( hv ) ) != 0 )
 | 
		
	
		
			
			|  | 179 | +	if ( ( rc = vmbus_wait_for_message ( hv, VMBUS_VERSION_RESPONSE ) ) !=0)
 | 
		
	
		
			
			| 148 | 180 |  		return rc;
 | 
		
	
		
			
			| 149 | 181 |  
 | 
		
	
		
			
			| 150 | 182 |  	/* Check response */
 | 
		
	
		
			
			| 151 |  | -	if ( version->header.type != cpu_to_le32 ( VMBUS_VERSION_RESPONSE ) ) {
 | 
		
	
		
			
			| 152 |  | -		DBGC ( vmbus, "VMBUS %p unexpected version response type %d\n",
 | 
		
	
		
			
			| 153 |  | -		       vmbus, le32_to_cpu ( version->header.type ) );
 | 
		
	
		
			
			| 154 |  | -		return -EPROTO;
 | 
		
	
		
			
			| 155 |  | -	}
 | 
		
	
		
			
			| 156 | 183 |  	if ( ! version->supported ) {
 | 
		
	
		
			
			| 157 | 184 |  		DBGC ( vmbus, "VMBUS %p requested version not supported\n",
 | 
		
	
		
			
			| 158 | 185 |  		       vmbus );
 | 
		
	
	
		
			
			|  | @@ -178,8 +205,6 @@ static int vmbus_initiate_contact ( struct hv_hypervisor *hv,
 | 
		
	
		
			
			| 178 | 205 |   * @ret rc		Return status code
 | 
		
	
		
			
			| 179 | 206 |   */
 | 
		
	
		
			
			| 180 | 207 |  static int vmbus_unload ( struct hv_hypervisor *hv ) {
 | 
		
	
		
			
			| 181 |  | -	struct vmbus *vmbus = hv->vmbus;
 | 
		
	
		
			
			| 182 |  | -	const struct vmbus_message_header *header = &vmbus->message->header;
 | 
		
	
		
			
			| 183 | 208 |  	int rc;
 | 
		
	
		
			
			| 184 | 209 |  
 | 
		
	
		
			
			| 185 | 210 |  	/* Post message */
 | 
		
	
	
		
			
			|  | @@ -187,16 +212,9 @@ static int vmbus_unload ( struct hv_hypervisor *hv ) {
 | 
		
	
		
			
			| 187 | 212 |  		return rc;
 | 
		
	
		
			
			| 188 | 213 |  
 | 
		
	
		
			
			| 189 | 214 |  	/* Wait for response */
 | 
		
	
		
			
			| 190 |  | -	if ( ( rc = vmbus_wait_for_message ( hv ) ) != 0 )
 | 
		
	
		
			
			|  | 215 | +	if ( ( rc = vmbus_wait_for_message ( hv, VMBUS_UNLOAD_RESPONSE ) ) != 0)
 | 
		
	
		
			
			| 191 | 216 |  		return rc;
 | 
		
	
		
			
			| 192 | 217 |  
 | 
		
	
		
			
			| 193 |  | -	/* Check response */
 | 
		
	
		
			
			| 194 |  | -	if ( header->type != cpu_to_le32 ( VMBUS_UNLOAD_RESPONSE ) ) {
 | 
		
	
		
			
			| 195 |  | -		DBGC ( vmbus, "VMBUS %p unexpected unload response type %d\n",
 | 
		
	
		
			
			| 196 |  | -		       vmbus, le32_to_cpu ( header->type ) );
 | 
		
	
		
			
			| 197 |  | -		return -EPROTO;
 | 
		
	
		
			
			| 198 |  | -	}
 | 
		
	
		
			
			| 199 |  | -
 | 
		
	
		
			
			| 200 | 218 |  	return 0;
 | 
		
	
		
			
			| 201 | 219 |  }
 | 
		
	
		
			
			| 202 | 220 |  
 | 
		
	
	
		
			
			|  | @@ -290,15 +308,10 @@ int vmbus_establish_gpadl ( struct vmbus_device *vmdev, userptr_t data,
 | 
		
	
		
			
			| 290 | 308 |  		return rc;
 | 
		
	
		
			
			| 291 | 309 |  
 | 
		
	
		
			
			| 292 | 310 |  	/* Wait for response */
 | 
		
	
		
			
			| 293 |  | -	if ( ( rc = vmbus_wait_for_message ( hv ) ) != 0 )
 | 
		
	
		
			
			|  | 311 | +	if ( ( rc = vmbus_wait_for_message ( hv, VMBUS_GPADL_CREATED ) ) != 0 )
 | 
		
	
		
			
			| 294 | 312 |  		return rc;
 | 
		
	
		
			
			| 295 | 313 |  
 | 
		
	
		
			
			| 296 | 314 |  	/* Check response */
 | 
		
	
		
			
			| 297 |  | -	if ( created->header.type != cpu_to_le32 ( VMBUS_GPADL_CREATED ) ) {
 | 
		
	
		
			
			| 298 |  | -		DBGC ( vmdev, "VMBUS %s unexpected GPADL response type %d\n",
 | 
		
	
		
			
			| 299 |  | -		       vmdev->dev.name, le32_to_cpu ( created->header.type ) );
 | 
		
	
		
			
			| 300 |  | -		return -EPROTO;
 | 
		
	
		
			
			| 301 |  | -	}
 | 
		
	
		
			
			| 302 | 315 |  	if ( created->channel != cpu_to_le32 ( vmdev->channel ) ) {
 | 
		
	
		
			
			| 303 | 316 |  		DBGC ( vmdev, "VMBUS %s unexpected GPADL channel %d\n",
 | 
		
	
		
			
			| 304 | 317 |  		       vmdev->dev.name, le32_to_cpu ( created->channel ) );
 | 
		
	
	
		
			
			|  | @@ -346,15 +359,10 @@ int vmbus_gpadl_teardown ( struct vmbus_device *vmdev, unsigned int gpadl ) {
 | 
		
	
		
			
			| 346 | 359 |  		return rc;
 | 
		
	
		
			
			| 347 | 360 |  
 | 
		
	
		
			
			| 348 | 361 |  	/* Wait for response */
 | 
		
	
		
			
			| 349 |  | -	if ( ( rc = vmbus_wait_for_message ( hv ) ) != 0 )
 | 
		
	
		
			
			|  | 362 | +	if ( ( rc = vmbus_wait_for_message ( hv, VMBUS_GPADL_TORNDOWN ) ) != 0 )
 | 
		
	
		
			
			| 350 | 363 |  		return rc;
 | 
		
	
		
			
			| 351 | 364 |  
 | 
		
	
		
			
			| 352 | 365 |  	/* Check response */
 | 
		
	
		
			
			| 353 |  | -	if ( torndown->header.type != cpu_to_le32 ( VMBUS_GPADL_TORNDOWN ) ) {
 | 
		
	
		
			
			| 354 |  | -		DBGC ( vmdev, "VMBUS %s unexpected GPADL response type %d\n",
 | 
		
	
		
			
			| 355 |  | -		       vmdev->dev.name, le32_to_cpu ( torndown->header.type ) );
 | 
		
	
		
			
			| 356 |  | -		return -EPROTO;
 | 
		
	
		
			
			| 357 |  | -	}
 | 
		
	
		
			
			| 358 | 366 |  	if ( torndown->gpadl != cpu_to_le32 ( gpadl ) ) {
 | 
		
	
		
			
			| 359 | 367 |  		DBGC ( vmdev, "VMBUS %s unexpected GPADL ID %#08x\n",
 | 
		
	
		
			
			| 360 | 368 |  		       vmdev->dev.name, le32_to_cpu ( torndown->gpadl ) );
 | 
		
	
	
		
			
			|  | @@ -443,15 +451,11 @@ int vmbus_open ( struct vmbus_device *vmdev,
 | 
		
	
		
			
			| 443 | 451 |  		return rc;
 | 
		
	
		
			
			| 444 | 452 |  
 | 
		
	
		
			
			| 445 | 453 |  	/* Wait for response */
 | 
		
	
		
			
			| 446 |  | -	if ( ( rc = vmbus_wait_for_message ( hv ) ) != 0 )
 | 
		
	
		
			
			|  | 454 | +	if ( ( rc = vmbus_wait_for_message ( hv,
 | 
		
	
		
			
			|  | 455 | +					     VMBUS_OPEN_CHANNEL_RESULT ) ) != 0)
 | 
		
	
		
			
			| 447 | 456 |  		return rc;
 | 
		
	
		
			
			| 448 | 457 |  
 | 
		
	
		
			
			| 449 | 458 |  	/* Check response */
 | 
		
	
		
			
			| 450 |  | -	if ( opened->header.type != cpu_to_le32 ( VMBUS_OPEN_CHANNEL_RESULT ) ){
 | 
		
	
		
			
			| 451 |  | -		DBGC ( vmdev, "VMBUS %s unexpected open response type %d\n",
 | 
		
	
		
			
			| 452 |  | -		       vmdev->dev.name, le32_to_cpu ( opened->header.type ) );
 | 
		
	
		
			
			| 453 |  | -		return -EPROTO;
 | 
		
	
		
			
			| 454 |  | -	}
 | 
		
	
		
			
			| 455 | 459 |  	if ( opened->channel != cpu_to_le32 ( vmdev->channel ) ) {
 | 
		
	
		
			
			| 456 | 460 |  		DBGC ( vmdev, "VMBUS %s unexpected opened channel %#08x\n",
 | 
		
	
		
			
			| 457 | 461 |  		       vmdev->dev.name, le32_to_cpu ( opened->channel ) );
 | 
		
	
	
		
			
			|  | @@ -1136,8 +1140,8 @@ static int vmbus_probe_channels ( struct hv_hypervisor *hv,
 | 
		
	
		
			
			| 1136 | 1140 |  	while ( 1 ) {
 | 
		
	
		
			
			| 1137 | 1141 |  
 | 
		
	
		
			
			| 1138 | 1142 |  		/* Wait for response */
 | 
		
	
		
			
			| 1139 |  | -		if ( ( rc = vmbus_wait_for_message ( hv ) ) != 0 )
 | 
		
	
		
			
			| 1140 |  | -			goto err_wait_for_message;
 | 
		
	
		
			
			|  | 1143 | +		if ( ( rc = vmbus_wait_for_any_message ( hv ) ) != 0 )
 | 
		
	
		
			
			|  | 1144 | +			goto err_wait_for_any_message;
 | 
		
	
		
			
			| 1141 | 1145 |  
 | 
		
	
		
			
			| 1142 | 1146 |  		/* Handle response */
 | 
		
	
		
			
			| 1143 | 1147 |  		if ( header->type == cpu_to_le32 ( VMBUS_OFFER_CHANNEL ) ) {
 | 
		
	
	
		
			
			|  | @@ -1223,7 +1227,7 @@ static int vmbus_probe_channels ( struct hv_hypervisor *hv,
 | 
		
	
		
			
			| 1223 | 1227 |  	}
 | 
		
	
		
			
			| 1224 | 1228 |   err_unexpected_offer:
 | 
		
	
		
			
			| 1225 | 1229 |   err_alloc_vmdev:
 | 
		
	
		
			
			| 1226 |  | - err_wait_for_message:
 | 
		
	
		
			
			|  | 1230 | + err_wait_for_any_message:
 | 
		
	
		
			
			| 1227 | 1231 |  	/* Free any devices allocated (but potentially not yet probed) */
 | 
		
	
		
			
			| 1228 | 1232 |  	list_for_each_entry_safe ( vmdev, tmp, &parent->children,
 | 
		
	
		
			
			| 1229 | 1233 |  				   dev.siblings ) {
 |