2014-11-14 23:36:49

by Dmitry Kalinkin

[permalink] [raw]
Subject: [PATCH 0/3] mmap() for vme_user and CR/CSR fix for master

Dear all,

mmap() on VME bridge devices is a feature present in many existing Linux and
UNIX drivers. The proposed solution follows the approach so that mmap()
offsets are coherent with read() and write() offsets, which seems to be the
only manner compatible with the current vme_user API. It also ends up adding
vme_master_mmap call to the VME subsystem API. On one hand this might come
useful for a board driver that will be able to expose one of its windows to the
user that way. On the other hand it introduces dependency on vma_area_struct
into vme.h, which doesn't seem very right.

Also I'm bringing up a bugfix by Martyn Welch that was published on the list,
but for some reason didn't make it to the kernel.

Cheers,
Dmitry

Dmitry Kalinkin (2):
staging: vme: use image mutex for ioctl()
staging: vme: mmap() support for vme_user

Martyn Welch (1):
vme: tsi148: Master windows support USERx and CR/CSR accesses, not
slaves

drivers/staging/vme/devices/vme_user.c | 94 ++++++++++++++++++++++++++++++++--
drivers/vme/bridges/vme_tsi148.c | 11 ++--
drivers/vme/vme.c | 26 ++++++++++
include/linux/vme.h | 1 +
4 files changed, 120 insertions(+), 12 deletions(-)

--
1.9.1


2014-11-14 23:36:51

by Dmitry Kalinkin

[permalink] [raw]
Subject: [PATCH 1/3] staging: vme: use image mutex for ioctl()

This implements more granular locking in vme_user_ioctl() by using separate
locks for each devfs device.

This also provides a synchronization between vme_user_read(), vme_user_write()
and vme_user_ioctl().

Signed-off-by: Dmitry Kalinkin <[email protected]>
Cc: Igor Alekseev <[email protected]>
---
drivers/staging/vme/devices/vme_user.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/staging/vme/devices/vme_user.c b/drivers/staging/vme/devices/vme_user.c
index 8b1f533..8731838 100644
--- a/drivers/staging/vme/devices/vme_user.c
+++ b/drivers/staging/vme/devices/vme_user.c
@@ -41,7 +41,6 @@

#include "vme_user.h"

-static DEFINE_MUTEX(vme_user_mutex);
static const char driver_name[] = "vme_user";

static int bus[VME_USER_BUS_MAX];
@@ -555,10 +554,12 @@ static long
vme_user_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
int ret;
+ struct inode *inode = file_inode(file);
+ unsigned int minor = MINOR(inode->i_rdev);

- mutex_lock(&vme_user_mutex);
- ret = vme_user_ioctl(file_inode(file), file, cmd, arg);
- mutex_unlock(&vme_user_mutex);
+ mutex_lock(&image[minor].mutex);
+ ret = vme_user_ioctl(inode, file, cmd, arg);
+ mutex_unlock(&image[minor].mutex);

return ret;
}
--
1.9.1

2014-11-14 23:37:34

by Dmitry Kalinkin

[permalink] [raw]
Subject: [PATCH 2/3] staging: vme: mmap() support for vme_user

We also make sure that user won't be able to reconfigure the window while it is
mmap'ed.

Signed-off-by: Dmitry Kalinkin <[email protected]>
Cc: Igor Alekseev <[email protected]>
---
drivers/staging/vme/devices/vme_user.c | 85 ++++++++++++++++++++++++++++++++++
drivers/vme/vme.c | 26 +++++++++++
include/linux/vme.h | 1 +
3 files changed, 112 insertions(+)

diff --git a/drivers/staging/vme/devices/vme_user.c b/drivers/staging/vme/devices/vme_user.c
index 8731838..b7fe1f0 100644
--- a/drivers/staging/vme/devices/vme_user.c
+++ b/drivers/staging/vme/devices/vme_user.c
@@ -17,6 +17,7 @@

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

+#include <linux/atomic.h>
#include <linux/cdev.h>
#include <linux/delay.h>
#include <linux/device.h>
@@ -99,6 +100,7 @@ struct image_desc {
struct device *device; /* Sysfs device */
struct vme_resource *resource; /* VME resource */
int users; /* Number of current users */
+ int mmap_count; /* Number of current mmap's */
};
static struct image_desc image[VME_DEVS];

@@ -134,6 +136,10 @@ static ssize_t vme_user_write(struct file *, const char __user *, size_t,
loff_t *);
static loff_t vme_user_llseek(struct file *, loff_t, int);
static long vme_user_unlocked_ioctl(struct file *, unsigned int, unsigned long);
+static int vme_user_mmap(struct file *file, struct vm_area_struct *vma);
+
+static void vme_user_vm_open(struct vm_area_struct *vma);
+static void vme_user_vm_close(struct vm_area_struct *vma);

static int vme_user_match(struct vme_dev *);
static int vme_user_probe(struct vme_dev *);
@@ -147,6 +153,17 @@ static const struct file_operations vme_user_fops = {
.llseek = vme_user_llseek,
.unlocked_ioctl = vme_user_unlocked_ioctl,
.compat_ioctl = vme_user_unlocked_ioctl,
+ .mmap = vme_user_mmap,
+};
+
+struct vme_user_vma_priv {
+ unsigned int minor;
+ atomic_t refcnt;
+};
+
+static const struct vm_operations_struct vme_user_vm_ops = {
+ .open = vme_user_vm_open,
+ .close = vme_user_vm_close,
};


@@ -488,6 +505,11 @@ static int vme_user_ioctl(struct inode *inode, struct file *file,

case VME_SET_MASTER:

+ if (image[minor].mmap_count != 0) {
+ pr_warn("Can't adjust mapped window\n");
+ return -EPERM;
+ }
+
copied = copy_from_user(&master, argp, sizeof(master));
if (copied != 0) {
pr_warn("Partial copy from userspace\n");
@@ -564,6 +586,69 @@ vme_user_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
return ret;
}

+static void vme_user_vm_open(struct vm_area_struct *vma)
+{
+ struct vme_user_vma_priv *vma_priv = vma->vm_private_data;
+
+ atomic_inc(&vma_priv->refcnt);
+}
+
+static void vme_user_vm_close(struct vm_area_struct *vma)
+{
+ struct vme_user_vma_priv *vma_priv = vma->vm_private_data;
+ unsigned int minor = vma_priv->minor;
+
+ if (!atomic_dec_and_test(&vma_priv->refcnt))
+ return;
+
+ mutex_lock(&image[minor].mutex);
+ image[minor].mmap_count--;
+ mutex_unlock(&image[minor].mutex);
+
+ kfree(vma_priv);
+}
+
+static int vme_user_master_mmap(unsigned int minor, struct vm_area_struct *vma)
+{
+ int err;
+ struct vme_user_vma_priv *vma_priv;
+
+ mutex_lock(&image[minor].mutex);
+
+ err = vme_master_mmap(image[minor].resource, vma);
+ if (err) {
+ mutex_unlock(&image[minor].mutex);
+ return err;
+ }
+
+ vma_priv = kmalloc(sizeof(struct vme_user_vma_priv), GFP_KERNEL);
+ if (vma_priv == NULL) {
+ mutex_unlock(&image[minor].mutex);
+ return -ENOMEM;
+ }
+
+ vma_priv->minor = minor;
+ atomic_set(&vma_priv->refcnt, 1);
+ vma->vm_ops = &vme_user_vm_ops;
+ vma->vm_private_data = vma_priv;
+
+ image[minor].mmap_count++;
+
+ mutex_unlock(&image[minor].mutex);
+
+ return 0;
+}
+
+static int vme_user_mmap(struct file *file, struct vm_area_struct *vma)
+{
+ unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev);
+
+ if (type[minor] == MASTER_MINOR)
+ return vme_user_master_mmap(minor, vma);
+
+ return -ENODEV;
+}
+

/*
* Unallocate a previously allocated buffer
diff --git a/drivers/vme/vme.c b/drivers/vme/vme.c
index 7516030..3dc62b4 100644
--- a/drivers/vme/vme.c
+++ b/drivers/vme/vme.c
@@ -609,6 +609,32 @@ unsigned int vme_master_rmw(struct vme_resource *resource, unsigned int mask,
}
EXPORT_SYMBOL(vme_master_rmw);

+int vme_master_mmap(struct vme_resource *resource, struct vm_area_struct *vma)
+{
+ struct vme_master_resource *image;
+ phys_addr_t phys_addr;
+ unsigned long vma_size;
+
+ if (resource->type != VME_MASTER) {
+ printk(KERN_ERR "Not a master resource\n");
+ return -EINVAL;
+ }
+
+ image = list_entry(resource->entry, struct vme_master_resource, list);
+ phys_addr = image->bus_resource.start + (vma->vm_pgoff << PAGE_SHIFT);
+ vma_size = vma->vm_end - vma->vm_start;
+
+ if (phys_addr + vma_size > image->bus_resource.end + 1) {
+ printk(KERN_ERR "Map size cannot exceed the window size\n");
+ return -EFAULT;
+ }
+
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+
+ return vm_iomap_memory(vma, phys_addr, vma->vm_end - vma->vm_start);
+}
+EXPORT_SYMBOL(vme_master_mmap);
+
void vme_master_free(struct vme_resource *resource)
{
struct vme_master_resource *master_image;
diff --git a/include/linux/vme.h b/include/linux/vme.h
index 8cd6f19..79242e9 100644
--- a/include/linux/vme.h
+++ b/include/linux/vme.h
@@ -137,6 +137,7 @@ ssize_t vme_master_read(struct vme_resource *, void *, size_t, loff_t);
ssize_t vme_master_write(struct vme_resource *, void *, size_t, loff_t);
unsigned int vme_master_rmw(struct vme_resource *, unsigned int, unsigned int,
unsigned int, loff_t);
+int vme_master_mmap(struct vme_resource *resource, struct vm_area_struct *vma);
void vme_master_free(struct vme_resource *);

struct vme_resource *vme_dma_request(struct vme_dev *, u32);
--
1.9.1

2014-11-14 23:37:32

by Dmitry Kalinkin

[permalink] [raw]
Subject: [PATCH 3/3] vme: tsi148: Master windows support USERx and CR/CSR accesses, not slaves

From: Martyn Welch <[email protected]>

The tsi148 driver is registering the slave images as supporting the "USER"
access modes and CR/CSR access mode rather than the master images as it
should.

Remove the incorrect case entries for these modes from the
tsi148_slave_set() function, stop registering slave_images as supporting
these modes and instead register master windows as supporting these modes.

Signed-off-by: Martyn Welch <[email protected]>
Acked-by: Dmitry Kalinkin <[email protected]>
---
drivers/vme/bridges/vme_tsi148.c | 11 +++--------
1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/drivers/vme/bridges/vme_tsi148.c b/drivers/vme/bridges/vme_tsi148.c
index e07cfa8..895c2a3 100644
--- a/drivers/vme/bridges/vme_tsi148.c
+++ b/drivers/vme/bridges/vme_tsi148.c
@@ -587,11 +587,6 @@ static int tsi148_slave_set(struct vme_slave_resource *image, int enabled,
granularity = 0x10000;
addr |= TSI148_LCSR_ITAT_AS_A64;
break;
- case VME_CRCSR:
- case VME_USER1:
- case VME_USER2:
- case VME_USER3:
- case VME_USER4:
default:
dev_err(tsi148_bridge->parent, "Invalid address space\n");
return -EINVAL;
@@ -2471,7 +2466,8 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id)
master_image->locked = 0;
master_image->number = i;
master_image->address_attr = VME_A16 | VME_A24 | VME_A32 |
- VME_A64;
+ VME_A64 | VME_CRCSR | VME_USER1 | VME_USER2 |
+ VME_USER3 | VME_USER4;
master_image->cycle_attr = VME_SCT | VME_BLT | VME_MBLT |
VME_2eVME | VME_2eSST | VME_2eSSTB | VME_2eSST160 |
VME_2eSST267 | VME_2eSST320 | VME_SUPER | VME_USER |
@@ -2500,8 +2496,7 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id)
slave_image->locked = 0;
slave_image->number = i;
slave_image->address_attr = VME_A16 | VME_A24 | VME_A32 |
- VME_A64 | VME_CRCSR | VME_USER1 | VME_USER2 |
- VME_USER3 | VME_USER4;
+ VME_A64;
slave_image->cycle_attr = VME_SCT | VME_BLT | VME_MBLT |
VME_2eVME | VME_2eSST | VME_2eSSTB | VME_2eSST160 |
VME_2eSST267 | VME_2eSST320 | VME_SUPER | VME_USER |
--
1.9.1

2014-11-15 07:51:46

by Dan Carpenter

[permalink] [raw]
Subject: Re: [PATCH 2/3] staging: vme: mmap() support for vme_user

On Sat, Nov 15, 2014 at 02:36:17AM +0300, Dmitry Kalinkin wrote:
> +int vme_master_mmap(struct vme_resource *resource, struct vm_area_struct *vma)
> +{
> + struct vme_master_resource *image;
> + phys_addr_t phys_addr;
> + unsigned long vma_size;
> +
> + if (resource->type != VME_MASTER) {
> + printk(KERN_ERR "Not a master resource\n");

Run your patch through scripts/checkpatch.pl

Also warning messages let people flood /var/log/messages so they can be
a DoS vector.

regards,
dan carpenter

2015-02-26 15:53:42

by Dmitry Kalinkin

[permalink] [raw]
Subject: [PATCHv2 0/3] mmap() for vme_user and CR/CSR fix for master

Dear all,

mmap() on VME bridge devices is a feature present in many existing Linux and
UNIX drivers. The proposed solution follows the approach so that mmap()
offsets are coherent with read() and write() offsets, which seems to be the
only manner compatible with the current vme_user API. It also ends up adding
vme_master_mmap call to the VME subsystem API. On one hand this might come
useful for a board driver that will be able to expose one of its windows to the
user that way. On the other hand it introduces dependency on vma_area_struct
into vme.h, which doesn't seem very right.

Also I'm bringing up a bugfix by Martyn Welch that was published on the list,
but for some reason didn't make it to the kernel.

CHANGES IN V2:
* use pr_* instead of printk
* use file_inode() helper

Cheers,
Dmitry

Dmitry Kalinkin (2):
staging: vme: use image mutex for ioctl()
staging: vme: mmap() support for vme_user

Martyn Welch (1):
vme: tsi148: Master windows support USERx and CR/CSR accesses, not
slaves

drivers/staging/vme/devices/vme_user.c | 94 ++++++++++++++++++++++++++++++++--
drivers/vme/bridges/vme_tsi148.c | 11 ++--
drivers/vme/vme.c | 26 ++++++++++
include/linux/vme.h | 1 +
4 files changed, 120 insertions(+), 12 deletions(-)

--
1.9.1

2015-02-26 15:53:49

by Dmitry Kalinkin

[permalink] [raw]
Subject: [PATCHv2 1/3] staging: vme: use image mutex for ioctl()

This implements more granular locking in vme_user_ioctl() by using separate
locks for each devfs device.

This also provides a synchronization between vme_user_read(), vme_user_write()
and vme_user_ioctl().

Signed-off-by: Dmitry Kalinkin <[email protected]>
Cc: Igor Alekseev <[email protected]>
---
drivers/staging/vme/devices/vme_user.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/staging/vme/devices/vme_user.c b/drivers/staging/vme/devices/vme_user.c
index 8b1f533..8731838 100644
--- a/drivers/staging/vme/devices/vme_user.c
+++ b/drivers/staging/vme/devices/vme_user.c
@@ -41,7 +41,6 @@

#include "vme_user.h"

-static DEFINE_MUTEX(vme_user_mutex);
static const char driver_name[] = "vme_user";

static int bus[VME_USER_BUS_MAX];
@@ -555,10 +554,12 @@ static long
vme_user_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
int ret;
+ struct inode *inode = file_inode(file);
+ unsigned int minor = MINOR(inode->i_rdev);

- mutex_lock(&vme_user_mutex);
- ret = vme_user_ioctl(file_inode(file), file, cmd, arg);
- mutex_unlock(&vme_user_mutex);
+ mutex_lock(&image[minor].mutex);
+ ret = vme_user_ioctl(inode, file, cmd, arg);
+ mutex_unlock(&image[minor].mutex);

return ret;
}
--
1.9.1

2015-02-26 15:54:24

by Dmitry Kalinkin

[permalink] [raw]
Subject: [PATCHv2 2/3] staging: vme: mmap() support for vme_user

We also make sure that user won't be able to reconfigure the window while it is
mmap'ed.

Signed-off-by: Dmitry Kalinkin <[email protected]>
Cc: Igor Alekseev <[email protected]>
---
drivers/staging/vme/devices/vme_user.c | 85 ++++++++++++++++++++++++++++++++++
drivers/vme/vme.c | 26 +++++++++++
include/linux/vme.h | 1 +
3 files changed, 112 insertions(+)

diff --git a/drivers/staging/vme/devices/vme_user.c b/drivers/staging/vme/devices/vme_user.c
index 8731838..b7fe1f0 100644
--- a/drivers/staging/vme/devices/vme_user.c
+++ b/drivers/staging/vme/devices/vme_user.c
@@ -17,6 +17,7 @@

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

+#include <linux/atomic.h>
#include <linux/cdev.h>
#include <linux/delay.h>
#include <linux/device.h>
@@ -99,6 +100,7 @@ struct image_desc {
struct device *device; /* Sysfs device */
struct vme_resource *resource; /* VME resource */
int users; /* Number of current users */
+ int mmap_count; /* Number of current mmap's */
};
static struct image_desc image[VME_DEVS];

@@ -134,6 +136,10 @@ static ssize_t vme_user_write(struct file *, const char __user *, size_t,
loff_t *);
static loff_t vme_user_llseek(struct file *, loff_t, int);
static long vme_user_unlocked_ioctl(struct file *, unsigned int, unsigned long);
+static int vme_user_mmap(struct file *file, struct vm_area_struct *vma);
+
+static void vme_user_vm_open(struct vm_area_struct *vma);
+static void vme_user_vm_close(struct vm_area_struct *vma);

static int vme_user_match(struct vme_dev *);
static int vme_user_probe(struct vme_dev *);
@@ -147,6 +153,17 @@ static const struct file_operations vme_user_fops = {
.llseek = vme_user_llseek,
.unlocked_ioctl = vme_user_unlocked_ioctl,
.compat_ioctl = vme_user_unlocked_ioctl,
+ .mmap = vme_user_mmap,
+};
+
+struct vme_user_vma_priv {
+ unsigned int minor;
+ atomic_t refcnt;
+};
+
+static const struct vm_operations_struct vme_user_vm_ops = {
+ .open = vme_user_vm_open,
+ .close = vme_user_vm_close,
};


@@ -488,6 +505,11 @@ static int vme_user_ioctl(struct inode *inode, struct file *file,

case VME_SET_MASTER:

+ if (image[minor].mmap_count != 0) {
+ pr_warn("Can't adjust mapped window\n");
+ return -EPERM;
+ }
+
copied = copy_from_user(&master, argp, sizeof(master));
if (copied != 0) {
pr_warn("Partial copy from userspace\n");
@@ -564,6 +586,69 @@ vme_user_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
return ret;
}

+static void vme_user_vm_open(struct vm_area_struct *vma)
+{
+ struct vme_user_vma_priv *vma_priv = vma->vm_private_data;
+
+ atomic_inc(&vma_priv->refcnt);
+}
+
+static void vme_user_vm_close(struct vm_area_struct *vma)
+{
+ struct vme_user_vma_priv *vma_priv = vma->vm_private_data;
+ unsigned int minor = vma_priv->minor;
+
+ if (!atomic_dec_and_test(&vma_priv->refcnt))
+ return;
+
+ mutex_lock(&image[minor].mutex);
+ image[minor].mmap_count--;
+ mutex_unlock(&image[minor].mutex);
+
+ kfree(vma_priv);
+}
+
+static int vme_user_master_mmap(unsigned int minor, struct vm_area_struct *vma)
+{
+ int err;
+ struct vme_user_vma_priv *vma_priv;
+
+ mutex_lock(&image[minor].mutex);
+
+ err = vme_master_mmap(image[minor].resource, vma);
+ if (err) {
+ mutex_unlock(&image[minor].mutex);
+ return err;
+ }
+
+ vma_priv = kmalloc(sizeof(struct vme_user_vma_priv), GFP_KERNEL);
+ if (vma_priv == NULL) {
+ mutex_unlock(&image[minor].mutex);
+ return -ENOMEM;
+ }
+
+ vma_priv->minor = minor;
+ atomic_set(&vma_priv->refcnt, 1);
+ vma->vm_ops = &vme_user_vm_ops;
+ vma->vm_private_data = vma_priv;
+
+ image[minor].mmap_count++;
+
+ mutex_unlock(&image[minor].mutex);
+
+ return 0;
+}
+
+static int vme_user_mmap(struct file *file, struct vm_area_struct *vma)
+{
+ unsigned int minor = MINOR(file_inode(file)->i_rdev);
+
+ if (type[minor] == MASTER_MINOR)
+ return vme_user_master_mmap(minor, vma);
+
+ return -ENODEV;
+}
+

/*
* Unallocate a previously allocated buffer
diff --git a/drivers/vme/vme.c b/drivers/vme/vme.c
index 7516030..3dc62b4 100644
--- a/drivers/vme/vme.c
+++ b/drivers/vme/vme.c
@@ -609,6 +609,32 @@ unsigned int vme_master_rmw(struct vme_resource *resource, unsigned int mask,
}
EXPORT_SYMBOL(vme_master_rmw);

+int vme_master_mmap(struct vme_resource *resource, struct vm_area_struct *vma)
+{
+ struct vme_master_resource *image;
+ phys_addr_t phys_addr;
+ unsigned long vma_size;
+
+ if (resource->type != VME_MASTER) {
+ pr_err("Not a master resource\n");
+ return -EINVAL;
+ }
+
+ image = list_entry(resource->entry, struct vme_master_resource, list);
+ phys_addr = image->bus_resource.start + (vma->vm_pgoff << PAGE_SHIFT);
+ vma_size = vma->vm_end - vma->vm_start;
+
+ if (phys_addr + vma_size > image->bus_resource.end + 1) {
+ pr_err("Map size cannot exceed the window size\n");
+ return -EFAULT;
+ }
+
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+
+ return vm_iomap_memory(vma, phys_addr, vma->vm_end - vma->vm_start);
+}
+EXPORT_SYMBOL(vme_master_mmap);
+
void vme_master_free(struct vme_resource *resource)
{
struct vme_master_resource *master_image;
diff --git a/include/linux/vme.h b/include/linux/vme.h
index 8cd6f19..79242e9 100644
--- a/include/linux/vme.h
+++ b/include/linux/vme.h
@@ -137,6 +137,7 @@ ssize_t vme_master_read(struct vme_resource *, void *, size_t, loff_t);
ssize_t vme_master_write(struct vme_resource *, void *, size_t, loff_t);
unsigned int vme_master_rmw(struct vme_resource *, unsigned int, unsigned int,
unsigned int, loff_t);
+int vme_master_mmap(struct vme_resource *resource, struct vm_area_struct *vma);
void vme_master_free(struct vme_resource *);

struct vme_resource *vme_dma_request(struct vme_dev *, u32);
--
1.9.1

2015-02-26 15:53:52

by Dmitry Kalinkin

[permalink] [raw]
Subject: [PATCHv2 3/3] vme: tsi148: Master windows support USERx and CR/CSR accesses, not slaves

From: Martyn Welch <[email protected]>

The tsi148 driver is registering the slave images as supporting the "USER"
access modes and CR/CSR access mode rather than the master images as it
should.

Remove the incorrect case entries for these modes from the
tsi148_slave_set() function, stop registering slave_images as supporting
these modes and instead register master windows as supporting these modes.

Signed-off-by: Martyn Welch <[email protected]>
Acked-by: Dmitry Kalinkin <[email protected]>
---
drivers/vme/bridges/vme_tsi148.c | 11 +++--------
1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/drivers/vme/bridges/vme_tsi148.c b/drivers/vme/bridges/vme_tsi148.c
index e07cfa8..895c2a3 100644
--- a/drivers/vme/bridges/vme_tsi148.c
+++ b/drivers/vme/bridges/vme_tsi148.c
@@ -587,11 +587,6 @@ static int tsi148_slave_set(struct vme_slave_resource *image, int enabled,
granularity = 0x10000;
addr |= TSI148_LCSR_ITAT_AS_A64;
break;
- case VME_CRCSR:
- case VME_USER1:
- case VME_USER2:
- case VME_USER3:
- case VME_USER4:
default:
dev_err(tsi148_bridge->parent, "Invalid address space\n");
return -EINVAL;
@@ -2471,7 +2466,8 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id)
master_image->locked = 0;
master_image->number = i;
master_image->address_attr = VME_A16 | VME_A24 | VME_A32 |
- VME_A64;
+ VME_A64 | VME_CRCSR | VME_USER1 | VME_USER2 |
+ VME_USER3 | VME_USER4;
master_image->cycle_attr = VME_SCT | VME_BLT | VME_MBLT |
VME_2eVME | VME_2eSST | VME_2eSSTB | VME_2eSST160 |
VME_2eSST267 | VME_2eSST320 | VME_SUPER | VME_USER |
@@ -2500,8 +2496,7 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id)
slave_image->locked = 0;
slave_image->number = i;
slave_image->address_attr = VME_A16 | VME_A24 | VME_A32 |
- VME_A64 | VME_CRCSR | VME_USER1 | VME_USER2 |
- VME_USER3 | VME_USER4;
+ VME_A64;
slave_image->cycle_attr = VME_SCT | VME_BLT | VME_MBLT |
VME_2eVME | VME_2eSST | VME_2eSSTB | VME_2eSST160 |
VME_2eSST267 | VME_2eSST320 | VME_SUPER | VME_USER |
--
1.9.1