Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 59c22904 authored by Martyn Welch's avatar Martyn Welch Committed by Greg Kroah-Hartman
Browse files

Staging: vme: Allow size of 0 when disabling a window



The TSI148 driver currently does not allow a size of zero to be passed to a
window. Zero is a valid value if the window is being disabled. Allow
windows to be disabled and their registers cleared.

Signed-off-by: default avatarMartyn Welch <martyn.welch@gefanuc.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 70d7aa88
Loading
Loading
Loading
Loading
+34 −22
Original line number Original line Diff line number Diff line
@@ -846,7 +846,7 @@ static int tsi148_alloc_resource(struct vme_master_resource *image,
		image->pci_resource.start);
		image->pci_resource.start);


	/* If the existing size is OK, return */
	/* If the existing size is OK, return */
	if (existing_size == (size - 1))
	if ((size != 0) && (existing_size == (size - 1)))
		return 0;
		return 0;


	if (existing_size != 0) {
	if (existing_size != 0) {
@@ -858,6 +858,11 @@ static int tsi148_alloc_resource(struct vme_master_resource *image,
		memset(&(image->pci_resource), 0, sizeof(struct resource));
		memset(&(image->pci_resource), 0, sizeof(struct resource));
	}
	}


	/* Exit here if size is zero */
	if (size == 0) {
		return 0;
	}

	if (image->pci_resource.name == NULL) {
	if (image->pci_resource.name == NULL) {
		image->pci_resource.name = kmalloc(VMENAMSIZ+3, GFP_KERNEL);
		image->pci_resource.name = kmalloc(VMENAMSIZ+3, GFP_KERNEL);
		if (image->pci_resource.name == NULL) {
		if (image->pci_resource.name == NULL) {
@@ -936,12 +941,13 @@ int tsi148_master_set( struct vme_master_resource *image, int enabled,


	/* Verify input data */
	/* Verify input data */
	if (vme_base & 0xFFFF) {
	if (vme_base & 0xFFFF) {
		printk("Invalid VME Window alignment\n");
		printk(KERN_ERR "Invalid VME Window alignment\n");
		retval = -EINVAL;
		retval = -EINVAL;
		goto err_window;
		goto err_window;
	}
	}
	if (size < 0x10000) {

		printk("Invalid VME Window size\n");
	if ((size == 0) && (enabled != 0)) {
		printk(KERN_ERR "Size must be non-zero for enabled windows\n");
		retval = -EINVAL;
		retval = -EINVAL;
		goto err_window;
		goto err_window;
	}
	}
@@ -949,26 +955,31 @@ int tsi148_master_set( struct vme_master_resource *image, int enabled,
	spin_lock(&(image->lock));
	spin_lock(&(image->lock));


	/* Let's allocate the resource here rather than further up the stack as
	/* Let's allocate the resource here rather than further up the stack as
	 * it avoids pushing loads of bus dependant stuff up the stack
	 * it avoids pushing loads of bus dependant stuff up the stack. If size
	 * is zero, any existing resource will be freed.
	 */
	 */
	retval = tsi148_alloc_resource(image, size);
	retval = tsi148_alloc_resource(image, size);
	if (retval) {
	if (retval) {
		spin_unlock(&(image->lock));
		spin_unlock(&(image->lock));
		printk(KERN_ERR "Unable to allocate memory for resource "
		printk(KERN_ERR "Unable to allocate memory for "
			"name\n");
			"resource\n");
		retval = -ENOMEM;
		goto err_res;
		goto err_res;
	}
	}


	if (size == 0) {
		pci_base = 0;
		pci_bound = 0;
		vme_offset = 0;
	} else {
		pci_base = (unsigned long long)image->pci_resource.start;
		pci_base = (unsigned long long)image->pci_resource.start;



		/*
		/*
		 * Bound address is a valid address for the window, adjust
		 * Bound address is a valid address for the window, adjust
		 * according to window granularity.
		 * according to window granularity.
		 */
		 */
		pci_bound = pci_base + (size - 0x10000);
		pci_bound = pci_base + (size - 0x10000);
		vme_offset = vme_base - pci_base;
		vme_offset = vme_base - pci_base;
	}


	/* Convert 64-bit variables to 2x 32-bit variables */
	/* Convert 64-bit variables to 2x 32-bit variables */
	reg_split(pci_base, &pci_base_high, &pci_base_low);
	reg_split(pci_base, &pci_base_high, &pci_base_low);
@@ -977,19 +988,19 @@ int tsi148_master_set( struct vme_master_resource *image, int enabled,


	if (pci_base_low & 0xFFFF) {
	if (pci_base_low & 0xFFFF) {
		spin_unlock(&(image->lock));
		spin_unlock(&(image->lock));
		printk("Invalid PCI base alignment\n");
		printk(KERN_ERR "Invalid PCI base alignment\n");
		retval = -EINVAL;
		retval = -EINVAL;
		goto err_gran;
		goto err_gran;
	}
	}
	if (pci_bound_low & 0xFFFF) {
	if (pci_bound_low & 0xFFFF) {
		spin_unlock(&(image->lock));
		spin_unlock(&(image->lock));
		printk("Invalid PCI bound alignment\n");
		printk(KERN_ERR "Invalid PCI bound alignment\n");
		retval = -EINVAL;
		retval = -EINVAL;
		goto err_gran;
		goto err_gran;
	}
	}
	if (vme_offset_low & 0xFFFF) {
	if (vme_offset_low & 0xFFFF) {
		spin_unlock(&(image->lock));
		spin_unlock(&(image->lock));
		printk("Invalid VME Offset alignment\n");
		printk(KERN_ERR "Invalid VME Offset alignment\n");
		retval = -EINVAL;
		retval = -EINVAL;
		goto err_gran;
		goto err_gran;
	}
	}
@@ -1049,7 +1060,8 @@ int tsi148_master_set( struct vme_master_resource *image, int enabled,
		temp_ctl |= TSI148_LCSR_OTAT_TM_2eSST;
		temp_ctl |= TSI148_LCSR_OTAT_TM_2eSST;
	}
	}
	if (cycle & VME_2eSSTB) {
	if (cycle & VME_2eSSTB) {
		printk("Currently not setting Broadcast Select Registers\n");
		printk(KERN_WARNING "Currently not setting Broadcast Select "
			"Registers\n");
		temp_ctl &= ~TSI148_LCSR_OTAT_TM_M;
		temp_ctl &= ~TSI148_LCSR_OTAT_TM_M;
		temp_ctl |= TSI148_LCSR_OTAT_TM_2eSSTB;
		temp_ctl |= TSI148_LCSR_OTAT_TM_2eSSTB;
	}
	}
@@ -1065,7 +1077,7 @@ int tsi148_master_set( struct vme_master_resource *image, int enabled,
		break;
		break;
	default:
	default:
		spin_unlock(&(image->lock));
		spin_unlock(&(image->lock));
		printk("Invalid data width\n");
		printk(KERN_ERR "Invalid data width\n");
		retval = -EINVAL;
		retval = -EINVAL;
		goto err_dwidth;
		goto err_dwidth;
	}
	}
@@ -1102,7 +1114,7 @@ int tsi148_master_set( struct vme_master_resource *image, int enabled,
		break;
		break;
	default:
	default:
		spin_unlock(&(image->lock));
		spin_unlock(&(image->lock));
		printk("Invalid address space\n");
		printk(KERN_ERR "Invalid address space\n");
		retval = -EINVAL;
		retval = -EINVAL;
		goto err_aspace;
		goto err_aspace;
		break;
		break;