/* Decrease the use count of a DCSS segment and remove it from the address space if nobody is using it any longer.  */
void segment_unload(char *name)
/* Decrease the use count of a DCSS segment and remove it from the address space if nobody is using it any longer.  */
void segment_unload(char *name)
{
	unsigned long dummy;
	struct dcss_segment *seg;
	if (!MACHINE_IS_VM)
		return;
	mutex_lock(&dcss_lock);
	seg = segment_by_name (name);
	if (seg == NULL) {
		pr_err("Unloading unknown DCSS %s failed\n", name);
		goto out_unlock;
	}
	if (atomic_dec_return(&seg->ref_count) != 0)
		goto out_unlock;
	release_resource(seg->res);
	kfree(seg->res);
	vmem_remove_mapping(seg->start_addr, seg->end - seg->start_addr + 1);
	list_del(&seg->list);
	dcss_diag(&purgeseg_scode, seg->dcss_name, &dummy, &dummy);
	kfree(seg);
out_unlock:
	mutex_unlock(&dcss_lock);
}