mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	Drivers: hv: vmbus: add an API vmbus_hvsock_device_unregister()
The hvsock driver needs this API to release all the resources related to the channel. Signed-off-by: Dexuan Cui <decui@microsoft.com> Signed-off-by: K. Y. Srinivasan <kys@microsoft.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
		
							parent
							
								
									499e8401a5
								
							
						
					
					
						commit
						85d9aa7051
					
				
					 3 changed files with 32 additions and 7 deletions
				
			
		| 
						 | 
				
			
			@ -310,6 +310,7 @@ void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid)
 | 
			
		|||
	vmbus_release_relid(relid);
 | 
			
		||||
 | 
			
		||||
	BUG_ON(!channel->rescind);
 | 
			
		||||
	BUG_ON(!mutex_is_locked(&vmbus_connection.channel_mutex));
 | 
			
		||||
 | 
			
		||||
	if (channel->target_cpu != get_cpu()) {
 | 
			
		||||
		put_cpu();
 | 
			
		||||
| 
						 | 
				
			
			@ -321,9 +322,7 @@ void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid)
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	if (channel->primary_channel == NULL) {
 | 
			
		||||
		mutex_lock(&vmbus_connection.channel_mutex);
 | 
			
		||||
		list_del(&channel->listentry);
 | 
			
		||||
		mutex_unlock(&vmbus_connection.channel_mutex);
 | 
			
		||||
 | 
			
		||||
		primary_channel = channel;
 | 
			
		||||
	} else {
 | 
			
		||||
| 
						 | 
				
			
			@ -367,6 +366,7 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
 | 
			
		|||
	bool fnew = true;
 | 
			
		||||
	unsigned long flags;
 | 
			
		||||
	u16 dev_type;
 | 
			
		||||
	int ret;
 | 
			
		||||
 | 
			
		||||
	/* Make sure this is a new offer */
 | 
			
		||||
	mutex_lock(&vmbus_connection.channel_mutex);
 | 
			
		||||
| 
						 | 
				
			
			@ -449,7 +449,11 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
 | 
			
		|||
	 * binding which eventually invokes the device driver's AddDevice()
 | 
			
		||||
	 * method.
 | 
			
		||||
	 */
 | 
			
		||||
	if (vmbus_device_register(newchannel->device_obj) != 0) {
 | 
			
		||||
	mutex_lock(&vmbus_connection.channel_mutex);
 | 
			
		||||
	ret = vmbus_device_register(newchannel->device_obj);
 | 
			
		||||
	mutex_unlock(&vmbus_connection.channel_mutex);
 | 
			
		||||
 | 
			
		||||
	if (ret != 0) {
 | 
			
		||||
		pr_err("unable to add child device object (relid %d)\n",
 | 
			
		||||
			newchannel->offermsg.child_relid);
 | 
			
		||||
		kfree(newchannel->device_obj);
 | 
			
		||||
| 
						 | 
				
			
			@ -725,6 +729,8 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr)
 | 
			
		|||
	struct device *dev;
 | 
			
		||||
 | 
			
		||||
	rescind = (struct vmbus_channel_rescind_offer *)hdr;
 | 
			
		||||
 | 
			
		||||
	mutex_lock(&vmbus_connection.channel_mutex);
 | 
			
		||||
	channel = relid2channel(rescind->child_relid);
 | 
			
		||||
 | 
			
		||||
	if (channel == NULL) {
 | 
			
		||||
| 
						 | 
				
			
			@ -733,7 +739,7 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr)
 | 
			
		|||
		 * vmbus_process_offer(), we have already invoked
 | 
			
		||||
		 * vmbus_release_relid() on error.
 | 
			
		||||
		 */
 | 
			
		||||
		return;
 | 
			
		||||
		goto out;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	spin_lock_irqsave(&channel->lock, flags);
 | 
			
		||||
| 
						 | 
				
			
			@ -743,7 +749,7 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr)
 | 
			
		|||
	if (channel->device_obj) {
 | 
			
		||||
		if (channel->chn_rescind_callback) {
 | 
			
		||||
			channel->chn_rescind_callback(channel);
 | 
			
		||||
			return;
 | 
			
		||||
			goto out;
 | 
			
		||||
		}
 | 
			
		||||
		/*
 | 
			
		||||
		 * We will have to unregister this device from the
 | 
			
		||||
| 
						 | 
				
			
			@ -758,8 +764,25 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr)
 | 
			
		|||
		hv_process_channel_removal(channel,
 | 
			
		||||
			channel->offermsg.child_relid);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
out:
 | 
			
		||||
	mutex_unlock(&vmbus_connection.channel_mutex);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void vmbus_hvsock_device_unregister(struct vmbus_channel *channel)
 | 
			
		||||
{
 | 
			
		||||
	mutex_lock(&vmbus_connection.channel_mutex);
 | 
			
		||||
 | 
			
		||||
	BUG_ON(!is_hvsock_channel(channel));
 | 
			
		||||
 | 
			
		||||
	channel->rescind = true;
 | 
			
		||||
	vmbus_device_unregister(channel->device_obj);
 | 
			
		||||
 | 
			
		||||
	mutex_unlock(&vmbus_connection.channel_mutex);
 | 
			
		||||
}
 | 
			
		||||
EXPORT_SYMBOL_GPL(vmbus_hvsock_device_unregister);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * vmbus_onoffers_delivered -
 | 
			
		||||
 * This is invoked when all offers have been delivered.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -288,7 +288,8 @@ struct vmbus_channel *relid2channel(u32 relid)
 | 
			
		|||
	struct list_head *cur, *tmp;
 | 
			
		||||
	struct vmbus_channel *cur_sc;
 | 
			
		||||
 | 
			
		||||
	mutex_lock(&vmbus_connection.channel_mutex);
 | 
			
		||||
	BUG_ON(!mutex_is_locked(&vmbus_connection.channel_mutex));
 | 
			
		||||
 | 
			
		||||
	list_for_each_entry(channel, &vmbus_connection.chn_list, listentry) {
 | 
			
		||||
		if (channel->offermsg.child_relid == relid) {
 | 
			
		||||
			found_channel = channel;
 | 
			
		||||
| 
						 | 
				
			
			@ -307,7 +308,6 @@ struct vmbus_channel *relid2channel(u32 relid)
 | 
			
		|||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	mutex_unlock(&vmbus_connection.channel_mutex);
 | 
			
		||||
 | 
			
		||||
	return found_channel;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1069,6 +1069,8 @@ int __must_check __vmbus_driver_register(struct hv_driver *hv_driver,
 | 
			
		|||
					 const char *mod_name);
 | 
			
		||||
void vmbus_driver_unregister(struct hv_driver *hv_driver);
 | 
			
		||||
 | 
			
		||||
void vmbus_hvsock_device_unregister(struct vmbus_channel *channel);
 | 
			
		||||
 | 
			
		||||
int vmbus_allocate_mmio(struct resource **new, struct hv_device *device_obj,
 | 
			
		||||
			resource_size_t min, resource_size_t max,
 | 
			
		||||
			resource_size_t size, resource_size_t align,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue