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);
 | 
						vmbus_release_relid(relid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	BUG_ON(!channel->rescind);
 | 
						BUG_ON(!channel->rescind);
 | 
				
			||||||
 | 
						BUG_ON(!mutex_is_locked(&vmbus_connection.channel_mutex));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (channel->target_cpu != get_cpu()) {
 | 
						if (channel->target_cpu != get_cpu()) {
 | 
				
			||||||
		put_cpu();
 | 
							put_cpu();
 | 
				
			||||||
| 
						 | 
					@ -321,9 +322,7 @@ void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (channel->primary_channel == NULL) {
 | 
						if (channel->primary_channel == NULL) {
 | 
				
			||||||
		mutex_lock(&vmbus_connection.channel_mutex);
 | 
					 | 
				
			||||||
		list_del(&channel->listentry);
 | 
							list_del(&channel->listentry);
 | 
				
			||||||
		mutex_unlock(&vmbus_connection.channel_mutex);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		primary_channel = channel;
 | 
							primary_channel = channel;
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
| 
						 | 
					@ -367,6 +366,7 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
 | 
				
			||||||
	bool fnew = true;
 | 
						bool fnew = true;
 | 
				
			||||||
	unsigned long flags;
 | 
						unsigned long flags;
 | 
				
			||||||
	u16 dev_type;
 | 
						u16 dev_type;
 | 
				
			||||||
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Make sure this is a new offer */
 | 
						/* Make sure this is a new offer */
 | 
				
			||||||
	mutex_lock(&vmbus_connection.channel_mutex);
 | 
						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()
 | 
						 * binding which eventually invokes the device driver's AddDevice()
 | 
				
			||||||
	 * method.
 | 
						 * 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",
 | 
							pr_err("unable to add child device object (relid %d)\n",
 | 
				
			||||||
			newchannel->offermsg.child_relid);
 | 
								newchannel->offermsg.child_relid);
 | 
				
			||||||
		kfree(newchannel->device_obj);
 | 
							kfree(newchannel->device_obj);
 | 
				
			||||||
| 
						 | 
					@ -725,6 +729,8 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr)
 | 
				
			||||||
	struct device *dev;
 | 
						struct device *dev;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rescind = (struct vmbus_channel_rescind_offer *)hdr;
 | 
						rescind = (struct vmbus_channel_rescind_offer *)hdr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mutex_lock(&vmbus_connection.channel_mutex);
 | 
				
			||||||
	channel = relid2channel(rescind->child_relid);
 | 
						channel = relid2channel(rescind->child_relid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (channel == NULL) {
 | 
						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_process_offer(), we have already invoked
 | 
				
			||||||
		 * vmbus_release_relid() on error.
 | 
							 * vmbus_release_relid() on error.
 | 
				
			||||||
		 */
 | 
							 */
 | 
				
			||||||
		return;
 | 
							goto out;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spin_lock_irqsave(&channel->lock, flags);
 | 
						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->device_obj) {
 | 
				
			||||||
		if (channel->chn_rescind_callback) {
 | 
							if (channel->chn_rescind_callback) {
 | 
				
			||||||
			channel->chn_rescind_callback(channel);
 | 
								channel->chn_rescind_callback(channel);
 | 
				
			||||||
			return;
 | 
								goto out;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		/*
 | 
							/*
 | 
				
			||||||
		 * We will have to unregister this device from the
 | 
							 * 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,
 | 
							hv_process_channel_removal(channel,
 | 
				
			||||||
			channel->offermsg.child_relid);
 | 
								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 -
 | 
					 * vmbus_onoffers_delivered -
 | 
				
			||||||
 * This is invoked when all offers have been 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 list_head *cur, *tmp;
 | 
				
			||||||
	struct vmbus_channel *cur_sc;
 | 
						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) {
 | 
						list_for_each_entry(channel, &vmbus_connection.chn_list, listentry) {
 | 
				
			||||||
		if (channel->offermsg.child_relid == relid) {
 | 
							if (channel->offermsg.child_relid == relid) {
 | 
				
			||||||
			found_channel = channel;
 | 
								found_channel = channel;
 | 
				
			||||||
| 
						 | 
					@ -307,7 +308,6 @@ struct vmbus_channel *relid2channel(u32 relid)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	mutex_unlock(&vmbus_connection.channel_mutex);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return found_channel;
 | 
						return found_channel;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1069,6 +1069,8 @@ int __must_check __vmbus_driver_register(struct hv_driver *hv_driver,
 | 
				
			||||||
					 const char *mod_name);
 | 
										 const char *mod_name);
 | 
				
			||||||
void vmbus_driver_unregister(struct hv_driver *hv_driver);
 | 
					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,
 | 
					int vmbus_allocate_mmio(struct resource **new, struct hv_device *device_obj,
 | 
				
			||||||
			resource_size_t min, resource_size_t max,
 | 
								resource_size_t min, resource_size_t max,
 | 
				
			||||||
			resource_size_t size, resource_size_t align,
 | 
								resource_size_t size, resource_size_t align,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue