diff options
Diffstat (limited to 'drivers/staging/vme')
-rw-r--r-- | drivers/staging/vme/boards/vme_vmivme7805.c | 4 | ||||
-rw-r--r-- | drivers/staging/vme/bridges/vme_ca91cx42.c | 19 | ||||
-rw-r--r-- | drivers/staging/vme/bridges/vme_tsi148.c | 2 | ||||
-rw-r--r-- | drivers/staging/vme/devices/vme_user.c | 53 | ||||
-rw-r--r-- | drivers/staging/vme/devices/vme_user.h | 6 | ||||
-rw-r--r-- | drivers/staging/vme/vme.h | 2 |
6 files changed, 65 insertions, 21 deletions
diff --git a/drivers/staging/vme/boards/vme_vmivme7805.c b/drivers/staging/vme/boards/vme_vmivme7805.c index 80eaa0c4fe1..8e05bb4e135 100644 --- a/drivers/staging/vme/boards/vme_vmivme7805.c +++ b/drivers/staging/vme/boards/vme_vmivme7805.c @@ -27,9 +27,9 @@ static void __exit vmic_exit(void); /** Base address to access FPGA register */ static void *vmic_base; -static char driver_name[] = "vmivme_7805"; +static const char driver_name[] = "vmivme_7805"; -static struct pci_device_id vmic_ids[] = { +static DEFINE_PCI_DEVICE_TABLE(vmic_ids) = { { PCI_DEVICE(PCI_VENDOR_ID_VMIC, PCI_DEVICE_ID_VTIMR) }, { }, }; diff --git a/drivers/staging/vme/bridges/vme_ca91cx42.c b/drivers/staging/vme/bridges/vme_ca91cx42.c index a4007287ef4..5122c13a956 100644 --- a/drivers/staging/vme/bridges/vme_ca91cx42.c +++ b/drivers/staging/vme/bridges/vme_ca91cx42.c @@ -42,7 +42,7 @@ static void __exit ca91cx42_exit(void); /* Module parameters */ static int geoid; -static char driver_name[] = "vme_ca91cx42"; +static const char driver_name[] = "vme_ca91cx42"; static DEFINE_PCI_DEVICE_TABLE(ca91cx42_ids) = { { PCI_DEVICE(PCI_VENDOR_ID_TUNDRA, PCI_DEVICE_ID_TUNDRA_CA91C142) }, @@ -190,7 +190,7 @@ static irqreturn_t ca91cx42_irqhandler(int irq, void *ptr) serviced |= ca91cx42_VIRQ_irqhandler(ca91cx42_bridge, stat); /* Clear serviced interrupts */ - iowrite32(stat, bridge->base + LINT_STAT); + iowrite32(serviced, bridge->base + LINT_STAT); return IRQ_HANDLED; } @@ -256,6 +256,18 @@ static void ca91cx42_irq_exit(struct ca91cx42_driver *bridge, free_irq(pdev->irq, pdev); } +static int ca91cx42_iack_received(struct ca91cx42_driver *bridge, int level) +{ + u32 tmp; + + tmp = ioread32(bridge->base + LINT_STAT); + + if (tmp & (1 << level)) + return 0; + else + return 1; +} + /* * Set up an VME interrupt */ @@ -311,7 +323,8 @@ static int ca91cx42_irq_generate(struct vme_bridge *ca91cx42_bridge, int level, iowrite32(tmp, bridge->base + VINT_EN); /* Wait for IACK */ - wait_event_interruptible(bridge->iack_queue, 0); + wait_event_interruptible(bridge->iack_queue, + ca91cx42_iack_received(bridge, level)); /* Return interrupt to low state */ tmp = ioread32(bridge->base + VINT_EN); diff --git a/drivers/staging/vme/bridges/vme_tsi148.c b/drivers/staging/vme/bridges/vme_tsi148.c index 106aa9daff4..9c539513c74 100644 --- a/drivers/staging/vme/bridges/vme_tsi148.c +++ b/drivers/staging/vme/bridges/vme_tsi148.c @@ -44,7 +44,7 @@ static void __exit tsi148_exit(void); static int err_chk; static int geoid; -static char driver_name[] = "vme_tsi148"; +static const char driver_name[] = "vme_tsi148"; static DEFINE_PCI_DEVICE_TABLE(tsi148_ids) = { { PCI_DEVICE(PCI_VENDOR_ID_TUNDRA, PCI_DEVICE_ID_TUNDRA_TSI148) }, diff --git a/drivers/staging/vme/devices/vme_user.c b/drivers/staging/vme/devices/vme_user.c index a571173249c..91d2cc7bb4c 100644 --- a/drivers/staging/vme/devices/vme_user.c +++ b/drivers/staging/vme/devices/vme_user.c @@ -41,7 +41,7 @@ #include "vme_user.h" static DEFINE_MUTEX(vme_user_mutex); -static char driver_name[] = "vme_user"; +static const char driver_name[] = "vme_user"; static int bus[USER_BUS_MAX]; static unsigned int bus_num; @@ -91,7 +91,7 @@ static unsigned int bus_num; /* * Structure to handle image related parameters. */ -typedef struct { +struct image_desc { void *kern_buf; /* Buffer address in kernel space */ dma_addr_t pci_buf; /* Buffer address in PCI address space */ unsigned long long size_buf; /* Buffer size */ @@ -99,10 +99,10 @@ typedef struct { struct device *device; /* Sysfs device */ struct vme_resource *resource; /* VME resource */ int users; /* Number of current users */ -} image_desc_t; -static image_desc_t image[VME_DEVS]; +}; +static struct image_desc image[VME_DEVS]; -typedef struct { +struct driver_stats { unsigned long reads; unsigned long writes; unsigned long ioctls; @@ -111,8 +111,8 @@ typedef struct { unsigned long dmaErrors; unsigned long timeouts; unsigned long external; -} driver_stats_t; -static driver_stats_t statistics; +}; +static struct driver_stats statistics; static struct cdev *vme_user_cdev; /* Character device */ static struct class *vme_user_sysfs_class; /* Sysfs class */ @@ -138,7 +138,7 @@ static long vme_user_unlocked_ioctl(struct file *, unsigned int, unsigned long); static int __devinit vme_user_probe(struct device *, int, int); static int __devexit vme_user_remove(struct device *, int, int); -static struct file_operations vme_user_fops = { +static const struct file_operations vme_user_fops = { .open = vme_user_open, .release = vme_user_release, .read = vme_user_read, @@ -168,8 +168,8 @@ static int vme_user_open(struct inode *inode, struct file *file) unsigned int minor = MINOR(inode->i_rdev); down(&image[minor].sem); - /* Only allow device to be opened if a resource is allocated */ - if (image[minor].resource == NULL) { + /* Allow device to be opened if a resource is needed and allocated. */ + if (minor < CONTROL_MINOR && image[minor].resource == NULL) { printk(KERN_ERR "No resources allocated for device\n"); err = -EINVAL; goto err_res; @@ -321,6 +321,9 @@ static ssize_t vme_user_read(struct file *file, char __user *buf, size_t count, size_t image_size; size_t okcount; + if (minor == CONTROL_MINOR) + return 0; + down(&image[minor].sem); /* XXX Do we *really* want this helper - we can use vme_*_get ? */ @@ -365,6 +368,9 @@ static ssize_t vme_user_write(struct file *file, const char __user *buf, size_t image_size; size_t okcount; + if (minor == CONTROL_MINOR) + return 0; + down(&image[minor].sem); image_size = vme_get_size(image[minor].resource); @@ -406,6 +412,9 @@ static loff_t vme_user_llseek(struct file *file, loff_t off, int whence) unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev); size_t image_size; + if (minor == CONTROL_MINOR) + return -EINVAL; + down(&image[minor].sem); image_size = vme_get_size(image[minor].resource); @@ -452,6 +461,7 @@ static int vme_user_ioctl(struct inode *inode, struct file *file, { struct vme_master master; struct vme_slave slave; + struct vme_irq_id irq_req; unsigned long copied; unsigned int minor = MINOR(inode->i_rdev); int retval; @@ -462,6 +472,21 @@ static int vme_user_ioctl(struct inode *inode, struct file *file, switch (type[minor]) { case CONTROL_MINOR: + switch (cmd) { + case VME_IRQ_GEN: + copied = copy_from_user(&irq_req, (char *)arg, + sizeof(struct vme_irq_id)); + if (copied != 0) { + printk(KERN_WARNING "Partial copy from userspace\n"); + return -EFAULT; + } + + retval = vme_irq_generate(vme_user_bridge, + irq_req.level, + irq_req.statid); + + return retval; + } break; case MASTER_MINOR: switch (cmd) { @@ -773,6 +798,7 @@ static int __devinit vme_user_probe(struct device *dev, int cur_bus, /* Add sysfs Entries */ for (i = 0; i < VME_DEVS; i++) { + int num; switch (type[i]) { case MASTER_MINOR: sprintf(name, "bus/vme/m%%d"); @@ -789,10 +815,9 @@ static int __devinit vme_user_probe(struct device *dev, int cur_bus, break; } - image[i].device = - device_create(vme_user_sysfs_class, NULL, - MKDEV(VME_MAJOR, i), NULL, name, - (type[i] == SLAVE_MINOR) ? i - (MASTER_MAX + 1) : i); + num = (type[i] == SLAVE_MINOR) ? i - (MASTER_MAX + 1) : i; + image[i].device = device_create(vme_user_sysfs_class, NULL, + MKDEV(VME_MAJOR, i), NULL, name, num); if (IS_ERR(image[i].device)) { printk(KERN_INFO "%s: Error creating sysfs device\n", driver_name); diff --git a/drivers/staging/vme/devices/vme_user.h b/drivers/staging/vme/devices/vme_user.h index ede77d7e766..24bf4e54013 100644 --- a/drivers/staging/vme/devices/vme_user.h +++ b/drivers/staging/vme/devices/vme_user.h @@ -43,10 +43,16 @@ struct vme_slave { #endif }; +struct vme_irq_id { + __u8 level; + __u8 statid; +}; + #define VME_GET_SLAVE _IOR(VME_IOC_MAGIC, 1, struct vme_slave) #define VME_SET_SLAVE _IOW(VME_IOC_MAGIC, 2, struct vme_slave) #define VME_GET_MASTER _IOR(VME_IOC_MAGIC, 3, struct vme_master) #define VME_SET_MASTER _IOW(VME_IOC_MAGIC, 4, struct vme_master) +#define VME_IRQ_GEN _IOW(VME_IOC_MAGIC, 5, struct vme_irq_id) #endif /* _VME_USER_H_ */ diff --git a/drivers/staging/vme/vme.h b/drivers/staging/vme/vme.h index 48768ca97e1..4155d8c2a53 100644 --- a/drivers/staging/vme/vme.h +++ b/drivers/staging/vme/vme.h @@ -98,7 +98,7 @@ struct vme_device_id { struct vme_driver { struct list_head node; - char *name; + const char *name; const struct vme_device_id *bind_table; int (*probe) (struct device *, int, int); int (*remove) (struct device *, int, int); |